diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 19dacfe7d7988a80ee71cfd342b2228bc576a048..ac9e3f380412904997dfeceaef45b3df00b2257d 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -63,7 +63,6 @@ endif() set(DEVICE_SRCS base/gpu/DeviceImage.cxx base/gpu/Params.cxx - detectors/sts/UnpackStsXpu.cxx detectors/sts/Hitfinder.cxx ) diff --git a/algo/base/gpu/xpu_legacy.h b/algo/base/gpu/xpu_legacy.h deleted file mode 100644 index 71e4f6bd6b158e133ae447f3a06516f666a39be8..0000000000000000000000000000000000000000 --- a/algo/base/gpu/xpu_legacy.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright (C) 2022 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main - SPDX-License-Identifier: GPL-3.0-only - Authors: Felix Weiglhofer [committer]*/ -#ifndef CORE_COMPAT_XPU_LEGACY_H -#define CORE_COMPAT_XPU_LEGACY_H - -#include <xpu/host.h> - -namespace xpu -{ - - inline constexpr auto host_to_device = xpu::h2d; - inline constexpr auto device_to_host = xpu::d2h; - - template<typename T> - class hd_buffer { - - public: - hd_buffer() = default; - hd_buffer(size_t size) : m_buffer(size, xpu::buf_io) {} - - T* h() { return xpu::h_view<T>(m_buffer).begin(); } - T* d() { return m_buffer.get(); } - - xpu::buffer<T>& underlying() { return m_buffer; } - - private: - xpu::buffer<T> m_buffer; - }; - - template<typename T> - class d_buffer { - - public: - d_buffer() = default; - d_buffer(size_t size) : m_buffer(size, xpu::buf_device) {} - - T* d() { return m_buffer.get(); } - - xpu::buffer<T>& underlying() { return m_buffer; } - - private: - xpu::buffer<T> m_buffer; - }; - - - template<typename T> - void copy(hd_buffer<T>& buf, direction dir) - { - static xpu::queue _Q; - _Q.copy(buf.underlying(), dir); - _Q.wait(); - } - - template<typename T> - void copy(T* dst, const T* src, size_t nelems) - { - static xpu::queue _Q; - _Q.copy(src, dst, nelems); - _Q.wait(); - } - - template<typename Kernel, typename... Args> - void run_kernel(xpu::grid params, Args&&... args) - { - static xpu::queue _Q; - _Q.launch<Kernel>(params, std::forward<Args>(args)...); - _Q.wait(); - } - - enum class side - { - host, - device - }; - - template<typename T, side S> - struct cmem_io { - using type = T*; - }; - - template<typename T> - struct cmem_io<T, side::host> { - using type = hd_buffer<T>; - }; - - template<typename T, side S> - using cmem_io_t = typename cmem_io<T, S>::type; - - template<typename T, side S> - struct cmem_device { - using type = T*; - }; - - template<typename T> - struct cmem_device<T, side::host> { - using type = d_buffer<T>; - }; - - template<typename T, side S> - using cmem_device_t = typename cmem_device<T, S>::type; - -} // namespace xpu - -#define XPU_BLOCK_SIZE_1D(...) - -#define XPU_EXPORT_KERNEL(Image, Kernel, ...) XPU_EXPORT_KERNEL_II(Image, Kernel, xpu::no_smem, 64, ##__VA_ARGS__) - -#define XPU_EXPORT_KERNEL_II(Image, Kernel, SMEM, BlockSize, ...) \ - struct Kernel : xpu::kernel<Image> { \ - using block_size = xpu::block_size<BlockSize>; \ - using context = xpu::kernel_context<SMEM>; \ - XPU_D void operator()(context& ctx, ##__VA_ARGS__); \ - } - -#define XPU_KERNEL(Kernel, smemIgnored, ...) \ - XPU_EXPORT(Kernel); \ - XPU_D void Kernel::operator()(context& ctx, ##__VA_ARGS__) - -#endif diff --git a/algo/detectors/sts/HitfinderChain.h b/algo/detectors/sts/HitfinderChain.h index 1926e3395be4d9b0ca184a50e69e4e1534d89750..8bd27cf5604438ba2ae93745c9b5d868499f37f6 100644 --- a/algo/detectors/sts/HitfinderChain.h +++ b/algo/detectors/sts/HitfinderChain.h @@ -9,7 +9,6 @@ #include "PartitionedSpan.h" #include "PartitionedVector.h" #include "SubChain.h" -#include "gpu/xpu_legacy.h" #include "sts/Hitfinder.h" #include "sts/HitfinderPars.h" #include "sts/LandauTable.h" @@ -21,6 +20,8 @@ #include <optional> #include <vector> +#include <xpu/host.h> + namespace cbm::algo::sts { diff --git a/algo/detectors/sts/UnpackStsXpu.cxx b/algo/detectors/sts/UnpackStsXpu.cxx deleted file mode 100644 index 8c66ec04da130fff07b4a29cc7f0c161b5448bb7..0000000000000000000000000000000000000000 --- a/algo/detectors/sts/UnpackStsXpu.cxx +++ /dev/null @@ -1,271 +0,0 @@ -/* Copyright (C) 2023 Facility for Antiproton and Ion Research in Europe, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Dominik Smith [committer] */ - -#include "UnpackStsXpu.h" - -#include "StsXyterMessage.h" - -#include <cassert> -#include <cmath> -#include <utility> -#include <vector> - -using std::unique_ptr; -using std::vector; - -XPU_KERNEL(cbm::algo::UnpackK, xpu::no_smem, UnpackStsXpuPar* params, UnpackStsXpuElinkPar* elinkParams, - stsxyter::Message* content, uint64_t* msMessCount, uint64_t* msMessOffset, uint64_t* msStartTime, - uint32_t* msCompIdx, CbmStsDigi* digisOut, const uint64_t currentTsTime, int NElems) -{ - int id = ctx.block_idx_x() * ctx.block_dim_x() + ctx.thread_idx_x(); - if (id >= NElems || msMessCount[id] < 2) return; // exit if out of bounds or too few messages - - UnpackStsXpuMonitorData monitor; //Monitor data, currently not stored. TO DO: Implement! - - // --- Get message count and offset for this MS - const uint32_t numMessages = msMessCount[id]; - const uint32_t messOffset = msMessOffset[id]; - - // --- Get starting position of this MS in message buffer - stsxyter::Message* message = &content[messOffset]; - - // --- Get starting position of this MS in digi buffer - CbmStsDigi* digis = &digisOut[messOffset]; - - // --- Get component index and unpack parameters of this MS - const uint32_t comp = msCompIdx[id]; - const UnpackStsXpuPar& unpackPar = params[comp]; - - // --- Get starting position of elink parameters of this MS - UnpackStsXpuElinkPar* elinkPar = &elinkParams[unpackPar.fElinkOffset]; - - // --- Init counter for produced digis - uint64_t numDigis = 0; - - // --- The first message in the MS is expected to be of type EPOCH and can be ignored. - if (message[0].GetMessType() != stsxyter::MessType::Epoch) { - monitor.fNumErrInvalidFirstMessage++; - msMessCount[id] = 0; - return; - } - - // --- The second message must be of type ts_msb. - if (message[1].GetMessType() != stsxyter::MessType::TsMsb) { - monitor.fNumErrInvalidFirstMessage++; - msMessCount[id] = 0; - return; - } - - // --- Current TS_MSB epoch cycle - uint64_t currentCycle = msStartTime[id] / UnpackStsXpu::fkCycleLength; - - // --- Process first message (ts_msb) - uint32_t currentEpoch = 0; ///< Current epoch number within epoch cycle - uint64_t currentEpochTime = 0; ///< Current epoch time relative to timeslice in clock cycles - UnpackStsXpu::ProcessTsmsbMessage(message[1], currentEpoch, currentEpochTime, currentCycle, currentTsTime); - - // --- Message loop - for (uint32_t messageNr = 2; messageNr < numMessages; messageNr++) { - - // --- Action depending on message type - switch (message[messageNr].GetMessType()) { - case stsxyter::MessType::Hit: { - UnpackStsXpu::ProcessHitMessage(message[messageNr], digis, numDigis, unpackPar, elinkPar, monitor, - currentEpochTime); - break; - } - case stsxyter::MessType::TsMsb: { - UnpackStsXpu::ProcessTsmsbMessage(message[messageNr], currentEpoch, currentEpochTime, currentCycle, - currentTsTime); - break; - } - default: { - monitor.fNumNonHitOrTsbMessage++; - break; - } - } - } - // --- Store number of digis in buffer - msMessCount[id] = numDigis; -} - - -namespace cbm::algo -{ - // ---- Algorithm execution --------------------------------------------- - UnpackStsXpu::resultType UnpackStsXpu::operator()(const fles::Timeslice* ts, sts::ReadoutConfigLegacy& config) - { - // --- Output data - resultType result = {}; - std::cout << "Called UnpackStsXpu::operator()()." << std::endl; - - // --- Init local storage vectors - std::vector<stsxyter::Message> messages; //storage of all messages - std::vector<uint64_t> messCount; //storage of number of messages per MS - std::vector<uint64_t> messOffset; //storage of MS offset in message buffer - std::vector<uint64_t> msIdx; //storage of MS idx / start time - std::vector<uint32_t> compIdx; //storage of comp idx for MS - - auto equipIdsSts = config.GetEquipmentIds(); - const size_t numStsComps = equipIdsSts.size(); - - // --- Loop over components in unpacker config - for (size_t comp = 0; comp < numStsComps; comp++) { - auto equip = equipIdsSts[comp]; - // --- Loop over components in timeslice - for (uint64_t tsComp = 0; tsComp < ts->num_components(); tsComp++) { - - // --- Skip if TS component is not from STS (equipment IDs are non-unique across systems) - auto subsystem = static_cast<fles::Subsystem>(ts->descriptor(tsComp, 0).sys_id); - if (subsystem != fles::Subsystem::STS) continue; - - if (equip == ts->descriptor(tsComp, 0).eq_id) { - const uint64_t numMsInComp = ts->num_microslices(tsComp); - for (uint64_t mslice = 0; mslice < numMsInComp; mslice++) { - const auto msDescr = ts->descriptor(tsComp, mslice); - if (msDescr.size % sizeof(stsxyter::Message) != 0) { - result.second.fNumErrInvalidMsSize++; - continue; - } - const uint32_t numMessages = msDescr.size / sizeof(stsxyter::Message); - if (numMessages < 2) { - result.second.fNumErrInvalidMsSize++; - continue; - } - xpu::t_add_bytes(msDescr.size); - xpu::k_add_bytes<UnpackK>(msDescr.size); - msIdx.push_back(msDescr.idx); - compIdx.push_back(comp); - messCount.push_back(numMessages); - messOffset.push_back(messages.size()); - const auto msContent = ts->content(tsComp, mslice); - auto mess = reinterpret_cast<const stsxyter::Message*>(msContent); - messages.insert(messages.end(), mess, mess + numMessages); - } - } - } - } - // --- Total number of microslices - const uint64_t numMs = messCount.size(); - - // --- Store SMX messages to be unpacked (TS content) - xpu::d_buffer<stsxyter::Message> tsContent{messages.size()}; - xpu::copy(tsContent.d(), messages.data(), messages.size()); - - // --- Store auxiliary host-device buffers - xpu::hd_buffer<uint64_t> msMessCount{numMs}; //modified by kernel, stores numDigis after execution - xpu::copy(msMessCount.d(), messCount.data(), messCount.size()); - - xpu::hd_buffer<uint64_t> msMessOffset{numMs}; //unchanged but needed on device and host - std::copy(messOffset.begin(), messOffset.end(), msMessOffset.h()); - xpu::copy(msMessOffset, xpu::host_to_device); - - // --- Store auxiliary device buffers - xpu::d_buffer<uint64_t> msStartTime{numMs}; - xpu::d_buffer<uint32_t> msCompIdx{numMs}; - xpu::copy(msStartTime.d(), msIdx.data(), msIdx.size()); - xpu::copy(msCompIdx.d(), compIdx.data(), compIdx.size()); - - // --- Create output buffer with maximum possible size - xpu::hd_buffer<CbmStsDigi> digisOut{messages.size()}; - - // --- Current Timeslice start time in epoch units. Note that it is always a multiple of epochs - // --- and the epoch is a multiple of ns. - const uint64_t epochLengthInNs = fkEpochLength * fkClockCycleNom / fkClockCycleDen; - const uint64_t currentTsTime = ts->start_time() / epochLengthInNs; - - // --- Do unpacking for each microslice - xpu::run_kernel<UnpackK>(xpu::n_threads(numMs), fParams.d(), fElinkParams.d(), tsContent.d(), msMessCount.d(), - msMessOffset.d(), msStartTime.d(), msCompIdx.d(), digisOut.d(), currentTsTime, numMs); - - // --- Copy results back to host (only two buffers are modified on device) - xpu::copy(msMessCount, xpu::device_to_host); - xpu::copy(digisOut, xpu::device_to_host); - - // --- Store digis TO DO: make Kernel for this, needs a way to sum arrays in XPU first - xpu::push_timer("Store digis"); - for (uint64_t i = 0; i < numMs; i++) { - uint64_t offset = msMessOffset.h()[i]; - uint64_t numDigis = msMessCount.h()[i]; - for (uint64_t j = 0; j < numDigis; j++) { - result.first.push_back(digisOut.h()[offset + j]); - } - } - xpu::pop_timer(); - - return result; - } - - // ----- Process hit message -------------------------------------------- - XPU_D inline void UnpackStsXpu::ProcessHitMessage(const stsxyter::Message& message, CbmStsDigi* digis, - uint64_t& numDigis, const UnpackStsXpuPar& unpackPar, - UnpackStsXpuElinkPar* elinkParams, UnpackStsXpuMonitorData& monitor, - const uint64_t currentEpochTime) - { - // --- Check eLink and get parameters - uint16_t elink = message.GetLinkIndexHitBinning(); - if (elink >= unpackPar.fNumElinks) { - monitor.fNumErrElinkOutOfRange++; - return; - } - const UnpackStsXpuElinkPar& elinkPar = elinkParams[elink]; - uint32_t asicNr = elinkPar.fAsicNr; - - // --- Hardware-to-software address - uint32_t channel = 0; - if (asicNr < unpackPar.fNumAsicsPerModule / 2) { // front side (n side); channels counted upward - channel = message.GetHitChannel() + unpackPar.fNumChansPerAsic * asicNr; - } - else { // back side (p side); channels counted downward - channel = unpackPar.fNumChansPerAsic * (asicNr + 1) - message.GetHitChannel() - 1; - } - - // --- Expand time stamp to time within timeslice (in clock cycle) - uint64_t messageTime = message.GetHitTimeBinning() + currentEpochTime; - - // --- Convert time stamp from clock cycles to ns. Round to nearest full ns. - messageTime = (messageTime * fkClockCycleNom + fkClockCycleDen / 2) / fkClockCycleDen; - - // --- Correct ASIC-wise offsets - messageTime -= elinkPar.fTimeOffset; - // --- TODO: Add walk correction (depends on ADC) - - // --- Charge - double charge = elinkPar.fAdcOffset + (message.GetHitAdc() - 1) * elinkPar.fAdcGain; - - // --- Create output digi - digis[numDigis] = CbmStsDigi(elinkPar.fAddress, channel, messageTime, charge); - numDigis++; - } - // -------------------------------------------------------------------------- - - - // ----- Process an epoch (TS_MSB) message ------------------------------ - XPU_D inline void UnpackStsXpu::ProcessTsmsbMessage(const stsxyter::Message& message, uint32_t& currentEpoch, - uint64_t& currentEpochTime, uint64_t& currentCycle, - const uint64_t currentTsTime) - { - // The compression of time is based on the hierarchy epoch cycle - epoch - message time. - // Cycles are counted from the start of Unix time and are multiples of an epoch (ts_msb). - // The epoch number is counted within each cycle. The time in the hit message is expressed - // in units of the readout clock cycle relative to the current epoch. - // The ts_msb message indicates the start of a new epoch. Its basic information is the epoch - // number within the current cycle. A cycle wrap resets the epoch number to zero, so it is - // indicated by the epoch number being smaller than the previous one (epoch messages are - // seemingly not consecutively in the data stream, but only if there are hit messages in between). - auto epoch = message.GetTsMsbValBinning(); - - // --- Cycle wrap - if (epoch < currentEpoch) currentCycle++; - - // --- Update current epoch counter - currentEpoch = epoch; - - // --- Calculate epoch time in clocks cycles relative to timeslice start time - currentEpochTime = (currentCycle * fkEpochsPerCycle + epoch - currentTsTime) * fkEpochLength; - } - // -------------------------------------------------------------------------- - - -} /* namespace cbm::algo */ diff --git a/algo/detectors/sts/UnpackStsXpu.h b/algo/detectors/sts/UnpackStsXpu.h deleted file mode 100644 index d30df029fcf0dbc799609256a8d56a778358716e..0000000000000000000000000000000000000000 --- a/algo/detectors/sts/UnpackStsXpu.h +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (C) 2023 Facility for Antiproton and Ion Research in Europe, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Dominik Smith [committer] */ - -#ifndef CBM_ALGO_UNPACKSTSXPU_H -#define CBM_ALGO_UNPACKSTSXPU_H 1 - - -#include "CbmStsDigi.h" -#include "MicrosliceDescriptor.hpp" -#include "ReadoutConfigLegacy.h" -#include "StsXyterMessage.h" -#include "Timeslice.hpp" -#include "gpu/DeviceImage.h" -#include "gpu/xpu_legacy.h" - -#include <cassert> -#include <cstddef> -#include <cstdint> -#include <memory> -#include <vector> - -#include <xpu/device.h> -#include <xpu/host.h> - - -namespace cbm::algo -{ - - /** @struct UnpackStsXpuElinkPar - ** @author Volker Friese <v.friese@gsi.de> - ** @since 25 November 2021 - ** @brief STS Unpacking parameters for one eLink / ASIC - **/ - struct UnpackStsXpuElinkPar { - int32_t fAddress = 0; ///< CbmStsAddress for the connected module - uint32_t fAsicNr = 0; ///< Number of connected ASIC within the module - uint64_t fTimeOffset = 0.; ///< Time calibration parameter - double fAdcOffset = 0.; ///< Charge calibration parameter - double fAdcGain = 0.; ///< Charge calibration parameter - }; - - - /** @struct UnpackStsXpuPar - ** @author Volker Friese <v.friese@gsi.de> - ** @since 25 November 2021 - ** @brief Parameters required for the STS unpacking (specific to one component) - **/ - struct UnpackStsXpuPar { - uint32_t fNumChansPerAsic = 0; ///< Number of channels per ASIC - uint32_t fNumAsicsPerModule = 0; ///< Number of ASICS per module - uint32_t fNumElinks = 0; ///< Number of elinks for this component - uint32_t fElinkOffset = 0; ///< Elink index offset for this component - }; - - - /** @struct UnpackStsXpuMoni - ** @author Volker Friese <v.friese@gsi.de> - ** @since 2 December 2021 - ** @brief Monitoring data for STS unpacking - **/ - struct UnpackStsXpuMonitorData { - uint32_t fNumNonHitOrTsbMessage = 0; - uint32_t fNumErrElinkOutOfRange = 0; ///< Elink not contained in parameters - uint32_t fNumErrInvalidFirstMessage = 0; ///< First message is not TS_MSB or second is not EPOCH - uint32_t fNumErrInvalidMsSize = 0; ///< Microslice size is not multiple of message size - uint32_t fNumErrTimestampOverflow = 0; ///< Overflow in 64 bit time stamp - bool HasErrors() - { - uint32_t numErrors = fNumNonHitOrTsbMessage + fNumErrElinkOutOfRange + fNumErrInvalidFirstMessage - + fNumErrInvalidMsSize + fNumErrTimestampOverflow; - return (numErrors > 0 ? true : false); - } - }; - - XPU_EXPORT_KERNEL(GPUReco, UnpackK, UnpackStsXpuPar* params, UnpackStsXpuElinkPar* elinkParams, - stsxyter::Message* content, uint64_t* msMessCount, uint64_t* msMessOffset, uint64_t* msStartTime, - uint32_t* msCompIdx, CbmStsDigi* digisOut, const uint64_t currentTsTime, int NElems); - - /** @class UnpackStsXpu - ** @author Pierre-Alain Loizeau <p.-a.loizeau@gsi.de> - ** @author Volker Friese <v.friese@gsi.de> - ** @since 25 November 2021 - ** @brief Unpack algorithm for STS - **/ - class UnpackStsXpu { - - public: - typedef std::pair<std::vector<CbmStsDigi>, UnpackStsXpuMonitorData> resultType; - - /** @brief Default constructor **/ - UnpackStsXpu(){}; - - - /** @brief Destructor **/ - ~UnpackStsXpu(){}; - - - /** @brief Algorithm execution - ** @return STS digi data - ** @param ts Timselice payload - ** @param config Configuration data - ** @return STS digi data - **/ - resultType operator()(const fles::Timeslice* ts, sts::ReadoutConfigLegacy& config); - - //Stores parameter structs for all elinks - xpu::hd_buffer<UnpackStsXpuElinkPar> fElinkParams; - - - //Stores parameter structs for all components - xpu::hd_buffer<UnpackStsXpuPar> fParams; - - - private: // methods - friend struct UnpackK; - - /** @brief Process a hit message - ** @param message SMX message (32-bit word) - ** @param digi buffer - ** @param digi counter - ** @param parameters for component - ** @param parameter buffer for elinks - ** @param reference to monitor object - ** @param current epoch number within epoch cycle - **/ - XPU_D static void ProcessHitMessage(const stsxyter::Message& message, CbmStsDigi* digis, uint64_t& numDigis, - const UnpackStsXpuPar& unpackPar, UnpackStsXpuElinkPar* elinkParams, - UnpackStsXpuMonitorData& monitor, const uint64_t currentEpochTime); - - /** @brief Process an epoch message (TS_MSB) - ** @param message SMX message (32-bit word) - ** @param current epoch number within epoch cycle - ** @param current epoch time relative to timeslice in clock cycles - ** @param current TS_MSB epoch cycle - **/ - XPU_D static void ProcessTsmsbMessage(const stsxyter::Message& message, uint32_t& currentEpoch, - uint64_t& currentEpochTime, uint64_t& currentCycle, - const uint64_t currentTsTime); - - private: // members - ///// To do: Make these available on device somehow - /** Number of TS_MSB epochs per cycle **/ - static constexpr uint64_t fkEpochsPerCycle = stsxyter::kuTsMsbNbTsBinsBinning; - - /** Length of TS_MSB epoch in clock cycles **/ - static constexpr uint64_t fkEpochLength = stsxyter::kuHitNbTsBinsBinning; - - /** Clock cycle nominator [ns] and denominator. The clock cycle in ns is nominator / denominator. **/ - static constexpr uint32_t fkClockCycleNom = stsxyter::kulClockCycleNom; - static constexpr uint32_t fkClockCycleDen = stsxyter::kulClockCycleDen; - - /** Epoch cycle length in ns **/ - static constexpr uint64_t fkCycleLength = (fkEpochsPerCycle * fkEpochLength * fkClockCycleNom) / fkClockCycleDen; - }; - - -} /* namespace cbm::algo */ - -#endif /* CBM_ALGO_UNPACKSTSXPU_H */ diff --git a/reco/tasks/CMakeLists.txt b/reco/tasks/CMakeLists.txt index ee2b8541c2541f662849480e9ec6f98eecb6dc4b..76d5677cc0654c8261dbc79e77c4ee7b95898241 100644 --- a/reco/tasks/CMakeLists.txt +++ b/reco/tasks/CMakeLists.txt @@ -18,7 +18,6 @@ set(SRCS CbmTaskTofClusterizer.cxx CbmTaskTofClusterizerParWrite.cxx CbmTaskUnpack.cxx - CbmTaskUnpackXpu.cxx ) diff --git a/reco/tasks/CbmRecoTasksLinkDef.h b/reco/tasks/CbmRecoTasksLinkDef.h index 3b84f429166ea88e85ec2626922898e8c5881bb9..8f829d3dfc1396d159981bfab070b6d89b98fd3a 100644 --- a/reco/tasks/CbmRecoTasksLinkDef.h +++ b/reco/tasks/CbmRecoTasksLinkDef.h @@ -22,7 +22,6 @@ #pragma link C++ class CbmTaskTofClusterizerParWrite + ; #pragma link C++ class CbmTaskTriggerDigi + ; #pragma link C++ class CbmTaskUnpack + ; -#pragma link C++ class CbmTaskUnpackXpu + ; //#pragma link C++ class cbm::algo::MainConfig + ; diff --git a/reco/tasks/CbmTaskUnpackXpu.cxx b/reco/tasks/CbmTaskUnpackXpu.cxx deleted file mode 100644 index 07d8fe1a589cb64d6904e1991458ddd41ff6b2f0..0000000000000000000000000000000000000000 --- a/reco/tasks/CbmTaskUnpackXpu.cxx +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright (C) 2023 Facility for Antiproton and Ion Research in Europe, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Dominik Smith [committer] */ - - -#include "CbmTaskUnpackXpu.h" - -#include "CbmDefs.h" -#include "CbmDigiBranchBase.h" -#include "CbmDigiEvent.h" -#include "CbmDigiManager.h" -#include "CbmDigiTimeslice.h" -#include "CbmSourceTs.h" - -#include "MicrosliceDescriptor.hpp" - -#include <FairRunOnline.h> -#include <Logger.h> - -#include <TStopwatch.h> - -#include <algorithm> -#include <cassert> -#include <cstdint> -#include <iomanip> -#include <memory> -#include <sstream> -#include <vector> - -#include <xpu/host.h> - -#include "compat/Algorithm.h" - -using namespace std; -using cbm::algo::UnpackStsXpuElinkPar; -using cbm::algo::UnpackStsXpuPar; - -// ----- Constructor ----------------------------------------------------- -CbmTaskUnpackXpu::CbmTaskUnpackXpu() : FairTask("Unpack") {} -// --------------------------------------------------------------------------- - - -// ----- Destructor ------------------------------------------------------ -CbmTaskUnpackXpu::~CbmTaskUnpackXpu() -{ - if (fTimeslice) delete fTimeslice; -} -// --------------------------------------------------------------------------- - - -// ----- Execution ------------------------------------------------------- -void CbmTaskUnpackXpu::Exec(Option_t*) -{ - // --- Reset output branch (CbmDigiTimeslice) - fTimeslice->Clear(); - - // --- Get FLES timeslice - assert(fSource); - fles::Timeslice* timeslice = fSource->GetTimeslice(); - assert(timeslice); - - // --- Timer and counters - TStopwatch timer; - timer.Start(); - - //Run STS unpacker and store result - auto resultSts = fAlgoStsXpu(timeslice, fStsConfig); - fTimeslice->fData.fSts.fDigis.insert(fTimeslice->fData.fSts.fDigis.end(), resultSts.first.begin(), - resultSts.first.end()); - - // --- Sorting of output digis. Is required by both digi trigger and event builder. - cbm::algo::Sort(fTimeslice->fData.fSts.fDigis.begin(), fTimeslice->fData.fSts.fDigis.end(), - [](CbmStsDigi digi1, CbmStsDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); - - - // --- Timeslice log - timer.Stop(); - stringstream logOut; - logOut << setw(15) << left << GetName() << " ["; - logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] "; - logOut << "TS " << fNumTs << " (index " << timeslice->index() << ")"; - logOut << ", digis " << fTimeslice->fData.fSts.fDigis.size(); - LOG(info) << logOut.str(); - - // --- Run statistics - fNumTs++; - // TO DO: implement these - //fNumMs += numMs; - //fNumBytes += numBytes; - //fNumDigis += numDigis; - fTime += timer.RealTime(); -} - - -// ----- End-of-run action ------------------------------------------------ -void CbmTaskUnpackXpu::Finish() -{ - double timePerTs = 1000. * fTime / double(fNumTs); // in ms - double rate = fNumBytes / 1.e6 / fTime; // in MB/s - LOG(info) << "====================================="; - LOG(info) << GetName() << ": Run summary"; - LOG(info) << "Timeslices : " << fNumTs; - LOG(info) << "Microslices : " << fNumMs; - LOG(info) << "Digis : " << fNumDigis; - LOG(info) << "Av. input rate : " << fixed << setprecision(2) << rate << " MB/s"; - LOG(info) << "Time / TS : " << fixed << setprecision(2) << timePerTs << " ms"; - LOG(info) << "====================================="; -} -// ---------------------------------------------------------------------------- - - -// ----- Initialisation --------------------------------------------------- -InitStatus CbmTaskUnpackXpu::Init() -{ - // FIXME: this has to be called only once - // and should happen during initialization not in reco loop - setenv("XPU_PROFILE", "1", 1); - xpu::initialize(); - - LOG(info) << "=================================================="; - LOG(info) << GetName() << ": Initialising..."; - - // --- Get source instance - fSource = dynamic_cast<CbmSourceTs*>(FairRunOnline::Instance()->GetSource()); - if (fSource == nullptr) { - LOG(error) << GetName() << ": No valid source class registered!"; - return kFATAL; - } - LOG(info) << "--- Found CbmSourceTs instance"; - - // --- Get FairRootManager instance - FairRootManager* ioman = FairRootManager::Instance(); - assert(ioman); - - // --- Register output array (CbmDigiTimeslice) - if (ioman->GetObject("DigiTimeslice")) { - LOG(fatal) << GetName() << ": Branch DigiTimeslice already exists!"; - return kFATAL; - } - fTimeslice = new CbmDigiTimeslice(); - ioman->RegisterAny("DigiTimeslice.", fTimeslice, IsOutputBranchPersistent("DigiTimeslice.")); - LOG(info) << "--- Registered branch DigiTimeslice."; - - // Initialize parameter buffers for STS - auto equipIdsSts = fStsConfig.GetEquipmentIds(); - const size_t numStsElinks = fStsConfig.GetNumElinks(); - const size_t numStsComps = equipIdsSts.size(); - fAlgoStsXpu.fParams = xpu::hd_buffer<UnpackStsXpuPar>(numStsComps); - fAlgoStsXpu.fElinkParams = xpu::hd_buffer<UnpackStsXpuElinkPar>(numStsElinks); - - // --- Common parameters for all components for STS - uint32_t numChansPerAsicSts = 128; // R/O channels per ASIC for STS - uint32_t numAsicsPerModuleSts = 16; // Number of ASICs per module for STS - - // Fill parameter buffers for STS - for (size_t comp = 0; comp < numStsComps; comp++) { - auto equip = equipIdsSts[comp]; - auto params = fAlgoStsXpu.fParams.h(); - auto numElinks = fStsConfig.GetNumElinks(equip); - params[comp].fNumElinks = numElinks; - params[comp].fNumChansPerAsic = numChansPerAsicSts; - params[comp].fNumAsicsPerModule = numAsicsPerModuleSts; - params[comp].fElinkOffset = (comp == 0) ? 0 : params[comp - 1].fElinkOffset + params[comp - 1].fNumElinks; - for (size_t elink = 0; elink < numElinks; elink++) { - UnpackStsXpuElinkPar& elinkPar = fAlgoStsXpu.fElinkParams.h()[params[comp].fElinkOffset + elink]; - auto mapEntry = fStsConfig.Map(equip, elink); - elinkPar.fAddress = mapEntry.first; // Module address for this elink - elinkPar.fAsicNr = mapEntry.second; // ASIC number within module - elinkPar.fTimeOffset = 0.; - elinkPar.fAdcOffset = 1.; - elinkPar.fAdcGain = 1.; - } - LOG(info) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; - } - xpu::copy(fAlgoStsXpu.fParams, xpu::host_to_device); - xpu::copy(fAlgoStsXpu.fElinkParams, xpu::host_to_device); - - return kSUCCESS; -} -// ---------------------------------------------------------------------------- - -ClassImp(CbmTaskUnpackXpu) diff --git a/reco/tasks/CbmTaskUnpackXpu.h b/reco/tasks/CbmTaskUnpackXpu.h deleted file mode 100644 index d67ac35e1a47d2e0a4bd8a98d23455ce5b90c65f..0000000000000000000000000000000000000000 --- a/reco/tasks/CbmTaskUnpackXpu.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (C) 2023 Facility for Antiproton and Ion Research in Europe, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Dominik Smith [committer] */ - - -#ifndef CBMTASKUNPACKXPU_H -#define CBMTASKUNPACKXPU_H 1 - -#include "CbmDefs.h" -#include "CbmDigiTimeslice.h" - -#include <FairTask.h> - -#include <sstream> -#include <vector> - -#include "EventBuilder.h" -#include "sts/ReadoutConfigLegacy.h" -#include "sts/UnpackStsXpu.h" - - -class CbmDigiManager; -class CbmSourceTs; - - -/** @class CbmTaskUnpackXpu - ** @brief Task class for associating digis to events - ** @author Volker Friese <v.friese@gsi.de> - ** @since 15.11.2021 - ** - ** Creates objects of class CbmDigiEvent and fills them with digi objects, - ** using the algorithm EventBuilder. - ** - ** TOFO: The current implementation is for STS only and with a dummy trigger list - ** just to establish the framework integration of algorithm and data interfaces. - **/ -class CbmTaskUnpackXpu : public FairTask { - - -public: - /** @brief Constructor **/ - CbmTaskUnpackXpu(); - - - /** @brief Copy constructor (disabled) **/ - CbmTaskUnpackXpu(const CbmTaskUnpackXpu&) = delete; - - - /** @brief Destructor **/ - virtual ~CbmTaskUnpackXpu(); - - - /** @brief Task execution **/ - virtual void Exec(Option_t* opt); - - - /** @brief Finish timeslice **/ - virtual void Finish(); - - - /** @brief Assignment operator (disabled) **/ - CbmTaskUnpackXpu& operator=(const CbmTaskUnpackXpu&) = delete; - - -private: // methods - /** @brief Task initialisation **/ - virtual InitStatus Init(); - -private: // members - CbmSourceTs* fSource = nullptr; - - cbm::algo::UnpackStsXpu fAlgoStsXpu; - cbm::algo::sts::ReadoutConfigLegacy fStsConfig {}; - - size_t fNumTs = 0; - size_t fNumMs = 0; - size_t fNumBytes = 0; - size_t fNumDigis = 0; - double fTime = 0.; - CbmDigiTimeslice* fTimeslice = nullptr; ///< Output data - - ClassDef(CbmTaskUnpackXpu, 1); -}; - -#endif /* CBMTASKUNPACKXPU_H */