From 369e479691ffcfbeb7758a147a0708e9beb6498a Mon Sep 17 00:00:00 2001
From: Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
Date: Tue, 16 May 2023 16:07:11 +0000
Subject: [PATCH] Add STS Unpacker and STS reco to toplevel reco.

---
 algo/CMakeLists.txt       |  5 ++-
 algo/global/Reco.cxx      | 94 +++++++++++++++++++++++++++++++++++++--
 algo/global/Reco.h        | 15 ++++++-
 reco/app/cbmreco/main.cxx | 57 ++++++++++++++++++++++--
 4 files changed, 163 insertions(+), 8 deletions(-)

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index 20414a13a1..b8d0864d46 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -11,13 +11,14 @@ set(DEVICE_SRCS
 set(SRCS
   ${DEVICE_SRCS}
   base/Options.cxx
+  base/util/TimingsFormat.cxx
   data/sts/LandauTable.cxx
   evbuild/EventBuilder.cxx
-  global/Reco.cxx
   trigger/TimeClusterTrigger.cxx
   evselector/DigiEventSelector.cxx
   detectors/sts/StsHitfinderChain.cxx
   detectors/sts/StsReadoutConfig.cxx
+  detectors/sts/StsUnpackChain.cxx
   detectors/sts/UnpackSts.cxx
   detectors/much/MuchReadoutConfig.cxx
   detectors/much/UnpackMuch.cxx
@@ -30,6 +31,7 @@ set(SRCS
   detectors/trd/UnpackTrd.cxx
   detectors/trd2d/Trd2dReadoutConfig.cxx
   detectors/trd2d/UnpackTrd2d.cxx
+  global/Reco.cxx
 )
 
 set(BUILD_INFO_CXX ${CMAKE_CURRENT_BINARY_DIR}/base/BuildInfo.cxx)
@@ -73,6 +75,7 @@ target_link_libraries(Algo
             GSL
             Boost::program_options
             xpu
+            external::yaml-cpp
   INTERFACE FairLogger::FairLogger
             external::fles_ipc
 )
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index d998332d4a..1954146892 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -3,11 +3,99 @@
    Authors: Felix Weiglhofer [committer] */
 #include "Reco.h"
 
+#include <xpu/host.h>
+
+#include "config/Yaml.h"
+#include "util/TimingsFormat.h"
+
 using namespace cbm::algo;
 
 Reco::Reco() {}
 Reco::~Reco() {}
 
-void Reco::Init(const Options&) {}
-void Reco::Run() {}
-void Reco::Finalize() {}
+void Reco::Init(const Options& opts)
+{
+  if (fInitialized) { throw std::runtime_error("Chain already initialized"); }
+
+  fContext.opts = opts;
+  SetContext(&fContext);
+  fUnpack.SetContext(&fContext);
+  fStsHitFinder.SetContext(&fContext);
+
+  xpu::device_prop props {xpu::device::active()};
+  LOG(info) << "Running CBM Reco on Device " << props.name();
+
+  // Reco Params
+  YAML::Node yaml     = YAML::LoadFile(opts.ParamsDir() / "RecoParams.yaml");
+  fContext.recoParams = config::Read<RecoParams>(yaml);
+
+  // STS Unpacker
+  // yaml = YAML::LoadFile(opts.ParamsDir() / "StsReadout.yaml");
+  // sts::ReadoutPars readoutConfig = config::Read<sts::ReadoutPars>(yaml);
+  StsReadoutConfig readoutConfig;
+  fUnpack.Init(readoutConfig);
+
+  // STS Hitfinder
+  yaml                               = YAML::LoadFile(opts.ParamsDir() / "StsHitfinder.yaml");
+  sts::HitfinderPars hitFinderConfig = config::Read<sts::HitfinderPars>(yaml);
+  hitFinderConfig.landauTable        = sts::LandauTable::FromFile(opts.ParamsDir() / "LandauWidthTable.txt");
+  fStsHitFinder.SetParameters(hitFinderConfig);
+
+  fInitialized = true;
+
+  xpu::push_timer("Reco");
+}
+
+void Reco::Run(const fles::Timeslice& ts)
+{
+  if (!fInitialized) { throw std::runtime_error("Chain not initialized"); }
+
+  for (uint64_t comp = 0; comp < ts.num_components(); comp++) {
+    xpu::t_add_bytes(ts.size_component(comp));
+  }
+
+  xpu::push_timer(fmt::format("TS {}", ts.index()));
+
+  LOG(info) << fair::Logger::startColor(fair::Logger::Color::fgRed) << ">>> Processing TS " << ts.index()
+            << fair::Logger::endColor();
+
+  xpu::set<cbm::algo::Params>(Params());
+
+  std::vector<CbmStsDigi> digis;
+  switch (Params().sts.unpackMode) {
+    case RecoParams::UnpackMode::XPU:
+      // digis = fUnpackXpu.Exec(ts);
+      throw std::runtime_error("XPU unpacker currently not implemented");
+      break;
+    default:
+    case RecoParams::UnpackMode::CPU: digis = fUnpack.Run(ts); break;
+  }
+  fStsHitFinder(digis);
+
+  xpu::timings ts_times = xpu::pop_timer();
+
+  PrintTimings(ts_times);
+}
+
+void Reco::Finalize()
+{
+  // Pop timer that was started in Init()
+  xpu::timings t = xpu::pop_timer();
+  if (Opts().CollectKernelTimes()) {
+    LOG(info) << MakeReportSubtimers("Run Summary", fTimesliceTimesAcc) << "\n" << MakeReportSummary("Total", t);
+  }
+  else {
+    LOG(info) << "Total Processing time (Wall): " << t.wall() << " ms";
+  }
+}
+
+void Reco::PrintTimings(xpu::timings& timings)
+{
+  if (Opts().CollectKernelTimes()) {
+    LOG(info) << MakeReportSubtimers("TS timings", timings) << "\n" << MakeReportSummary("Total", timings);
+    fTimesliceTimesAcc.merge(timings);
+  }
+  else {
+    LOG(info) << "TS Processing time (Wall): " << timings.wall() << " ms";
+  }
+}
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index de4faf5500..9303d9c220 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -4,6 +4,10 @@
 #ifndef CBM_ALGO_GLOBAL_RECO_H
 #define CBM_ALGO_GLOBAL_RECO_H
 
+#include <xpu/host.h>
+
+#include "StsHitfinderChain.h"
+#include "StsUnpackChain.h"
 #include "SubChain.h"
 
 namespace fles
@@ -26,12 +30,21 @@ namespace cbm::algo
     Reco& operator=(Reco&&) = delete;
 
     void Init(const Options&);
-    void Run();
+    void Run(const fles::Timeslice&);
     void Finalize();
+    void PrintTimings(xpu::timings&);
 
   private:
     bool fInitialized = false;
     ChainContext fContext;
+    xpu::timings fTimesliceTimesAcc;
+
+    // STS
+    sts::UnpackChain fUnpack;
+    sts::HitfinderChain fStsHitFinder;
+
+    // Util functions
+    void AddTiming(xpu::timings& timings);
   };
 }  // namespace cbm::algo
 
diff --git a/reco/app/cbmreco/main.cxx b/reco/app/cbmreco/main.cxx
index bdee3f8582..543f576c8c 100644
--- a/reco/app/cbmreco/main.cxx
+++ b/reco/app/cbmreco/main.cxx
@@ -1,16 +1,67 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
+#include <TimesliceAutoSource.hpp>
+
+#include <fairlogger/Logger.h>
+
+#include <sstream>
+
+#include <xpu/host.h>
+
 #include "Options.h"
 #include "Reco.h"
 
+using namespace cbm::algo;
+
 int main(int argc, char** argv)
 {
-  cbm::algo::Options opts {argc, argv};
+  Options opts {argc, argv};
+
+  // Logger
+  fair::Logger::SetConsoleSeverity(std::string {opts.LogLevel()});
+  if (fair::Logger::GetConsoleSeverity() == fair::Severity::trace) {
+    fair::Logger::SetVerbosity(fair::Verbosity::veryhigh);
+  }
+  fair::Logger::OnFatal([] { std::abort(); });
+  fair::Logger::SetConsoleColor(true);
 
-  cbm::algo::Reco reco {};
+  // XPU
+  xpu::settings settings;
+  settings.profile = opts.CollectKernelTimes();
+  settings.device  = opts.Device();
+  if (fair::Logger::GetConsoleSeverity() == fair::Severity::trace) {
+    settings.verbose      = true;
+    settings.logging_sink = [](std::string_view msg) { LOG(trace) << msg; };
+  }
+  xpu::initialize(settings);
+  xpu::preload<GPUReco>();
+
+  // LOG(info) << "CORE buildType=" << BuildInfo::BUILD_TYPE << " gpuDebug=" << BuildInfo::GPU_DEBUG << " commit=" << BuildInfo::GIT_HASH;
+  std::stringstream ss;
+  for (int i = 0; i < argc; i++) {
+    ss << argv[i] << " ";
+  }
+  LOG(info) << ss.str();
+
+  Reco reco;
   reco.Init(opts);
-  reco.Run();
+
+  fles::TimesliceAutoSource source {opts.InputLocator()};
+  int tsIdx  = 0;
+  int num_ts = opts.NumTimeslices();
+  if (num_ts > 0) { num_ts += opts.SkipTimeslices(); }
+  while (auto ts = source.get()) {
+    if (tsIdx < opts.SkipTimeslices()) {
+      tsIdx++;
+      continue;
+    }
+    reco.Run(*ts);
+    tsIdx++;
+
+    if (num_ts > 0 && tsIdx >= num_ts) { break; }
+  }
+
   reco.Finalize();
 
   return 0;
-- 
GitLab