diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 61662120dc8..1242a69ae75 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,7 +66,7 @@ build_gnn_cpu: - > cmake -B build -S src --preset=gitlab-ci-gnn - -DACTS_GNN_ENABLE_CUDA=OFF + -DACTS_ENABLE_CUDA=OFF -DACTS_GNN_ENABLE_MODULEMAP=OFF - ccache -z diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ec389a8ec7..87f5b3216ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,11 +81,22 @@ option(ACTS_BUILD_PLUGIN_EDM4HEP "Build EDM4hep plugin" OFF) option(ACTS_BUILD_PLUGIN_FPEMON "Build FPE monitoring plugin" OFF) option(ACTS_BUILD_PLUGIN_GEOMODEL "Build GeoModel plugin" OFF) option(ACTS_BUILD_PLUGIN_TRACCC "Build Traccc plugin" OFF) +option(ACTS_ENABLE_CUDA "Enable CUDA for the gnn/Traccc plugins" OFF) +option(ACTS_GNN_ENABLE_CUDA "[Deprecated] Enable CUDA for the gnn plugin" OFF) + +# Preserve previous behaviour of ACTS_GNN_ENABLE_CUDA but mark as deprecated +if(ACTS_GNN_ENABLE_CUDA) + message( + DEPRECATION + "ACTS_GNN_ENABLE_CUDA is deprecated. Enable ACTS_ENABLE_CUDA to achieve the same effect." + ) + set(ACTS_ENABLE_CUDA ON) +endif() + option(ACTS_BUILD_PLUGIN_GEANT4 "Build Geant4 plugin" OFF) option(ACTS_BUILD_PLUGIN_GNN "Build the GNN plugin" OFF) option(ACTS_GNN_ENABLE_ONNX "Build the Onnx backend for the gnn plugin" OFF) option(ACTS_GNN_ENABLE_TORCH "Build the torchscript backend for the gnn plugin" ON) -option(ACTS_GNN_ENABLE_CUDA "Enable CUDA for the gnn plugin" OFF) option(ACTS_GNN_ENABLE_MODULEMAP "Enable Module-Map-based graph construction" OFF) option(ACTS_GNN_ENABLE_TENSORRT "Enable the native TensorRT inference modules" OFF) option(ACTS_BUILD_PLUGIN_JSON "Build json plugin" OFF) @@ -207,7 +218,12 @@ set_option_if(ACTS_BUILD_PLUGIN_GNN ACTS_BUILD_EXAMPLES_GNN) set_option_if(ACTS_BUILD_PLUGIN_FPEMON ACTS_BUILD_EXAMPLES) set_option_if(ACTS_BUILD_PLUGIN_JSON ACTS_BUILD_PLUGIN_TRACCC) set_option_if(ACTS_BUILD_PLUGIN_ACTSVG ACTS_BUILD_PLUGIN_TRACCC) -set_option_if(ACTS_GNN_ENABLE_CUDA ACTS_GNN_ENABLE_MODULEMAP) +set_option_if( + ACTS_ENABLE_CUDA + ACTS_GNN_ENABLE_MODULEMAP + AND + ACTS_BUILD_PLUGIN_GNN +) set_option_if(ACTS_BUILD_PYTHON_BINDINGS ACTS_BUILD_PYTHON_WHEEL) set_option_if(ACTS_BUILD_ALIGNMENT ACTS_BUILD_PLUGIN_MILLE) @@ -502,7 +518,7 @@ if(ACTS_BUILD_ANALYSIS_APPS) ) endif() if(ACTS_BUILD_PLUGIN_GNN) - if(ACTS_GNN_ENABLE_CUDA) + if(ACTS_ENABLE_CUDA) find_package(CUDAToolkit REQUIRED) enable_cuda() message(STATUS "Build GNN plugin with CUDA") @@ -511,7 +527,7 @@ if(ACTS_BUILD_PLUGIN_GNN) endif() if(ACTS_GNN_ENABLE_TORCH) find_package(Torch REQUIRED) - if(ACTS_GNN_ENABLE_CUDA) + if(ACTS_ENABLE_CUDA) add_subdirectory(thirdparty/FRNN) endif() endif() @@ -576,6 +592,12 @@ if(ACTS_BUILD_PLUGIN_TRACCC) endif() endif() + if(ACTS_ENABLE_CUDA) + message(STATUS "Build Traccc plugin with CUDA support") + else() + message(STATUS "Build Traccc plugin for CPU only") + endif() + # traccc also depends on vecmem and covfie, but those plugins should always # be enabled if traccc is. if(ACTS_USE_SYSTEM_TRACCC) diff --git a/CMakePresets.json b/CMakePresets.json index 9875eb257d3..98cd0082d31 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -155,7 +155,7 @@ "ACTS_BUILD_EXAMPLES_GNN": "ON", "ACTS_GNN_ENABLE_TORCH": "ON", "ACTS_GNN_ENABLE_ONNX": "ON", - "ACTS_GNN_ENABLE_CUDA": "ON", + "ACTS_ENABLE_CUDA": "ON", "ACTS_GNN_ENABLE_MODULEMAP": "ON", "ACTS_USE_SYSTEM_NLOHMANN_JSON": "ON", "ACTS_USE_SYSTEM_PYBIND11": "ON" diff --git a/Examples/Algorithms/CMakeLists.txt b/Examples/Algorithms/CMakeLists.txt index 97b25ece9cf..7ce8e6ef8e5 100644 --- a/Examples/Algorithms/CMakeLists.txt +++ b/Examples/Algorithms/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory_if(GeneratorsPythia8 ACTS_BUILD_EXAMPLES_PYTHIA8) add_subdirectory(MaterialMapping) add_subdirectory(Printers) add_subdirectory(Propagation) +add_subdirectory_if(Traccc ACTS_BUILD_PLUGIN_TRACCC) add_subdirectory_if(Detray ACTS_BUILD_PLUGIN_DETRAY) add_subdirectory(TrackFinding) add_subdirectory_if(TrackFindingGnn ACTS_BUILD_EXAMPLES_GNN) diff --git a/Examples/Algorithms/Detray/include/ActsExamples/Detray/DetrayPropagator.hpp b/Examples/Algorithms/Detray/include/ActsExamples/Detray/DetrayPropagator.hpp index 58be8c1e32e..bb8c6904739 100644 --- a/Examples/Algorithms/Detray/include/ActsExamples/Detray/DetrayPropagator.hpp +++ b/Examples/Algorithms/Detray/include/ActsExamples/Detray/DetrayPropagator.hpp @@ -138,7 +138,6 @@ class DetrayPropagator : public PropagatorInterface { // Propagator with empty actor chain (for the moment) using Propagator = detray::propagator>; - detray::propagation::config prop_cfg{}; auto dCtx = prop_cfg.context; diff --git a/Examples/Algorithms/Traccc/CMakeLists.txt b/Examples/Algorithms/Traccc/CMakeLists.txt new file mode 100644 index 00000000000..558779bcd26 --- /dev/null +++ b/Examples/Algorithms/Traccc/CMakeLists.txt @@ -0,0 +1,35 @@ +acts_add_library( + ExamplesTraccc + SHARED + src/TracccChain.cpp + src/TracccSeqAlg.cpp + src/ActsMeasToTracccAlg.cpp + src/ActsSpToTracccAlg.cpp +) + +target_include_directories( + ActsExamplesTraccc + PUBLIC + $ + $ +) + +target_link_libraries( + ActsExamplesTraccc + PUBLIC + Acts::Core + Acts::ExamplesFramework + traccc::core + detray::core + detray::io + traccc::io + vecmem::core +) + +if(ACTS_ENABLE_CUDA) + target_compile_definitions(ActsExamplesTraccc PRIVATE ACTS_ENABLE_CUDA) + target_link_libraries( + ActsExamplesTraccc + PRIVATE traccc::cuda traccc::device_common vecmem::cuda + ) +endif() diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/ActsMeasToTracccAlg.hpp b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/ActsMeasToTracccAlg.hpp new file mode 100644 index 00000000000..4541cc18145 --- /dev/null +++ b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/ActsMeasToTracccAlg.hpp @@ -0,0 +1,71 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/SpacePointFormation2/PixelSpacePointBuilder.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" + +#include +#include + +#include +#include +#include + +#include "traccc/geometry/detector.hpp" +#include "traccc/geometry/host_detector.hpp" +#include "traccc/io/read_detector.hpp" + +namespace ActsExamples { + +class ActsMeasToTracccAlg final : public IAlgorithm { + public: + struct Config { + std::string detectorFile = ""; + std::string inputActsMeasurements = "measurements"; + std::string outputDetrayToActsMap = "detray-to-acts-map"; + std::string outputTracccMeasurements = "acts-to-traccc-measurements"; + std::vector pixelVolumes; + std::shared_ptr trackingGeometry; + }; + + mutable vecmem::host_memory_resource m_mr; + traccc::host_detector m_host_det; + std::unordered_map m_actsToDetrayMap; + std::unordered_map m_detrayToActsMap; + + explicit ActsMeasToTracccAlg( + const Config& cfg, std::unique_ptr logger = nullptr); + + ProcessCode execute(const AlgorithmContext& ctx) const override; + void buildSurfaceMap( + const Acts::TrackingGeometry& trackingGeometry, + const std::string& detectorFile, + std::unordered_map& + m_detrayToActsMap, + std::unordered_map& + m_actsToDetrayMap); + const Config& config() const { return m_cfg; } + + private: + Config m_cfg; + + ReadDataHandle m_inputActsMeasurements{ + this, "inputActsMeasurements"}; + WriteDataHandle> + m_outputDetrayToActsMap{this, "outputDetrayToActsMap"}; + WriteDataHandle + m_outputTracccMeasurements{this, "outputTracccMeasurements"}; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/ActsSpToTracccAlg.hpp b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/ActsSpToTracccAlg.hpp new file mode 100644 index 00000000000..2fc57e48c67 --- /dev/null +++ b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/ActsSpToTracccAlg.hpp @@ -0,0 +1,50 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/EventData/SpacePoint.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" + +#include +#include + +#include +#include + +namespace ActsExamples { + +class ActsSpToTracccAlg final : public IAlgorithm { + public: + struct Config { + std::string inputSpacePoints = "spacepoints"; + std::string outputTracccSpacepoints = "acts-traccc-spacepoints"; + }; + + explicit ActsSpToTracccAlg( + const Config& cfg, std::unique_ptr logger = nullptr); + + ProcessCode execute(const AlgorithmContext& ctx) const override; + const Config& config() const { return m_cfg; } + + mutable vecmem::host_memory_resource m_mr; + + private: + Config m_cfg; + + ReadDataHandle m_inputSpacePoints{this, + "inputSpacePoints"}; + WriteDataHandle + m_outputTracccSpacepoints{this, "outputTracccSpacepoints"}; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/TracccChain.hpp b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/TracccChain.hpp new file mode 100644 index 00000000000..231ddc3521d --- /dev/null +++ b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/TracccChain.hpp @@ -0,0 +1,85 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Utilities/Logger.hpp" + +#include +#include + +#include "traccc/ambiguity_resolution/greedy_ambiguity_resolution_algorithm.hpp" +#include "traccc/clusterization/clustering_config.hpp" +#include "traccc/clusterization/clusterization_algorithm.hpp" +#include "traccc/edm/measurement_collection.hpp" +#include "traccc/edm/spacepoint_collection.hpp" +#include "traccc/finding/combinatorial_kalman_filter_algorithm.hpp" +#include "traccc/fitting/kalman_fitting_algorithm.hpp" +#include "traccc/seeding/detail/seeding_config.hpp" +#include "traccc/seeding/detail/track_params_estimation_config.hpp" +#include "traccc/seeding/seeding_algorithm.hpp" +#include "traccc/seeding/silicon_pixel_spacepoint_formation_algorithm.hpp" +#include "traccc/seeding/track_params_estimation.hpp" + +namespace ActsExamples::Traccc { + +struct TracccChainConfig { + enum class Backend { CPU, CUDA }; + Backend backend = Backend::CPU; + + // Detector files + std::string detectorFile; + std::string digitizationFile; + std::string conditionsFile; + std::string gridFile; + std::string materialFile; + + // Magnetic field file + std::string magneticFieldFile; + // z-component used by CPU track_params_estimation + float bFieldInZ = 2.0f; + + // Algorithm configs + traccc::clustering_config clusteringConfig; + traccc::seedfinder_config seedfinderConfig; + traccc::seedfilter_config seedfilterConfig; + traccc::track_params_estimation_config trackParamsEstConfig; + traccc::finding_config findingConfig; + traccc::fitting_config fittingConfig; + traccc::host::greedy_ambiguity_resolution_algorithm::config_type + resolutionConfig; +}; + +struct EventResult { + std::size_t n_measurements = 0; + std::size_t n_spacepoints = 0; + std::size_t n_seeds = 0; + std::size_t n_track_candidates = 0; + std::size_t n_fitted_tracks = 0; +}; + +class TracccChain { + public: + struct Impl; + + explicit TracccChain(const TracccChainConfig& cfg, + Acts::Logging::Level logLevel = Acts::Logging::INFO); + ~TracccChain(); + + TracccChain(TracccChain&&) noexcept; + TracccChain& operator=(TracccChain&&) noexcept; + + EventResult operator()( + traccc::edm::measurement_collection::host& measurements, + traccc::edm::spacepoint_collection::host& spacepoints) const; + + private: + std::unique_ptr m_impl; +}; + +} // namespace ActsExamples::Traccc diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/TracccSeqAlg.hpp b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/TracccSeqAlg.hpp new file mode 100644 index 00000000000..4bfc43dac22 --- /dev/null +++ b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/TracccSeqAlg.hpp @@ -0,0 +1,49 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" +#include "ActsExamples/Traccc/TracccChain.hpp" + +#include + +#include "traccc/edm/silicon_cell_collection.hpp" + +namespace ActsExamples::Traccc { + +class TracccSeqAlg final : public IAlgorithm { + public: + struct Config { + /// Full traccc chain configuration (geometry, seeding params, etc.) + TracccChainConfig chain; + + /// WhiteBoard key for the input collections + std::string inputMeasurements = ""; + std::string inputSpacepoints = ""; + }; + + explicit TracccSeqAlg(const Config& cfg, + std::unique_ptr logger = nullptr); + + ProcessCode execute(const AlgorithmContext& ctx) const override; + const Config& config() const { return m_cfg; } + + private: + Config m_cfg; + TracccChain m_chain; + + ReadDataHandle m_inputMeasurements{ + this, "inputMeasurements"}; + ReadDataHandle m_inputSpacepoints{ + this, "inputSpacepoints"}; +}; + +} // namespace ActsExamples::Traccc diff --git a/Examples/Algorithms/Traccc/src/ActsMeasToTracccAlg.cpp b/Examples/Algorithms/Traccc/src/ActsMeasToTracccAlg.cpp new file mode 100644 index 00000000000..51ee6704bce --- /dev/null +++ b/Examples/Algorithms/Traccc/src/ActsMeasToTracccAlg.cpp @@ -0,0 +1,213 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Traccc/ActsMeasToTracccAlg.hpp" + +#include "ActsExamples/Framework/AlgorithmContext.hpp" +#include + +#include + +#include + +namespace ActsExamples { + +ActsMeasToTracccAlg::ActsMeasToTracccAlg( + const Config& cfg, std::unique_ptr logger) + : IAlgorithm("ActsMeasToTracccAlg", std::move(logger)), m_cfg(cfg) { + if (!m_cfg.trackingGeometry) { + throw std::invalid_argument( + "TracccMeasToActsAlg: trackingGeometry is null"); + } + m_inputActsMeasurements.initialize(m_cfg.inputActsMeasurements); + m_outputDetrayToActsMap.initialize(m_cfg.outputDetrayToActsMap); + m_outputTracccMeasurements.initialize(m_cfg.outputTracccMeasurements); + + if (m_detrayToActsMap.empty()) { + buildSurfaceMap(*m_cfg.trackingGeometry, m_cfg.detectorFile, + m_detrayToActsMap, m_actsToDetrayMap); + } +} + +void ActsExamples::ActsMeasToTracccAlg::buildSurfaceMap( + const Acts::TrackingGeometry& trackingGeometry, + const std::string& detectorFile, + std::unordered_map& + detrayToActsMap, + std::unordered_map& + actsToDetrayMap) { + std::unordered_map> + actsCentres; + std::unordered_map> detrayCentres; + + // Load detray detector and build Acts→detray map + traccc::io::read_detector(m_host_det, m_mr, detectorFile, "", ""); + + int nPrint = 0; + typename traccc::default_detector::host::geometry_context detrayContext{}; + traccc::host_detector_visitor( + m_host_det, [&]( + const typename detector_traits_t::host& det) { + for (const auto& surface : det.surfaces()) { + if (!surface.is_sensitive()) + continue; + const auto sf = detray::geometry::surface{det, surface}; + + double placement_x = sf.center(detrayContext)[0]; + double placement_y = sf.center(detrayContext)[1]; + double placement_z = sf.center(detrayContext)[2]; + if (nPrint < 10) { + ACTS_INFO("detray=" << surface.identifier().value() << " pos: " + << placement_x << ", " << placement_y << ", " + << placement_z << std::endl); + nPrint++; + } + detrayCentres[surface.identifier().value()] = + std::array{placement_x, placement_y, placement_z}; + } + }); + + ACTS_INFO("ActsMeasToTracccAlg: built detray map with " + << detrayCentres.size() << " entries" << std::endl); + + nPrint = 0; + Acts::GeometryContext gctx = + Acts::GeometryContext::dangerouslyDefaultConstruct(); + trackingGeometry.visitSurfaces([&](const Acts::Surface* surface) { + if (surface != nullptr) { + Acts::Vector3 geo_center = surface->center(gctx); + if (nPrint < 10) { + ACTS_INFO("acts=" << surface->geometryId() << " pos: " << geo_center[0] + << ", " << geo_center[1] << ", " << geo_center[2] + << std::endl); + nPrint++; + } + actsCentres[surface->geometryId()] = + std::array{geo_center[0], geo_center[1], geo_center[2]}; + } + }); + + ACTS_INFO("ActsMeasToTracccAlg: built acts map with " + << actsCentres.size() << " entries" << std::endl); + + for (const auto& [detrayID, detrayCenter] : detrayCentres) { + for (auto& [actsID, actsCenter] : actsCentres) { + double distance = std::sqrt(std::pow(detrayCenter[0] - actsCenter[0], 2) + + std::pow(detrayCenter[1] - actsCenter[1], 2) + + std::pow(detrayCenter[2] - actsCenter[2], 2)); + if (distance < 0.1) { // threshold for matching, may need tuning + detrayToActsMap[detrayID] = actsID; + actsToDetrayMap[actsID] = detrayID; + break; + } + } + } + + ACTS_INFO("ActsMeasToTracccAlg: built detray to Acts map with " + << detrayToActsMap.size() << " entries" << std::endl); +} + +ProcessCode ActsMeasToTracccAlg::execute(const AlgorithmContext& ctx) const { + const auto& actsMeasurements = m_inputActsMeasurements(ctx); + const auto& detrayToActsMap = m_detrayToActsMap; + // Build inverse map: Acts GeometryIdentifier → detray identifier + m_outputDetrayToActsMap( + ctx, std::unordered_map( + m_detrayToActsMap)); + std::unordered_map actsToDetrayMap; + for (const auto& [detrayId, actsId] : detrayToActsMap) { + actsToDetrayMap[actsId.value()] = detrayId; + } + + traccc::edm::measurement_collection::host tracccMeasurements{m_mr}; + + std::size_t nConverted = 0; + std::size_t nPix = 0, nStripShort = 0, nStripLong = 0; + for (std::size_t i = 0; i < actsMeasurements.size(); ++i) { + const auto meas = actsMeasurements.getMeasurement(i); + const auto geoId = meas.geometryId(); + const auto dims = static_cast(meas.size()); + + if (dims == 0u) + continue; + + auto it = actsToDetrayMap.find(geoId.value()); + if (it == actsToDetrayMap.end()) { + ACTS_WARNING("ActsMeasToTracccAlg: no detray id for Acts geo id " + << geoId); + continue; + } + + tracccMeasurements.push_back({}); + auto tm = tracccMeasurements.at(tracccMeasurements.size() - 1); + + const auto vol = geoId.volume(); + if (std::find(m_cfg.pixelVolumes.begin(), m_cfg.pixelVolumes.end(), vol) != + m_cfg.pixelVolumes.end()) { + nPix++; + // Pixel (dims=2 or 3 with timing) + tm.dimensions() = 2u; + tm.local_position()[0] = meas.parameters()[Acts::eBoundLoc0]; + tm.local_position()[1] = meas.parameters()[Acts::eBoundLoc1]; + tm.local_variance()[0] = meas.covariance()(0, 0); + tm.local_variance()[1] = meas.covariance()(1, 1); + tm.subspace()[0] = 0u; + tm.subspace()[1] = 1u; + + } else { + // 1D measurement - determine if long strip (1D in traccc) or short strip + // (2D in traccc) + + if (dims == 2u) { + // Short strip barrel: 2D in traccc with large cross-strip variance + tm.dimensions() = 2u; + tm.local_position()[0] = meas.parameters()[Acts::eBoundLoc0]; + tm.local_position()[1] = meas.parameters()[Acts::eBoundLoc1]; + tm.local_variance()[0] = meas.covariance()(0, 0); + tm.local_variance()[1] = meas.covariance()(1, 1); + tm.subspace()[0] = 0u; + tm.subspace()[1] = 1u; + nStripShort++; + + } else { + // Everything else (long strips barrel/endcap, short strip endcap): 1D + tm.dimensions() = 1u; + tm.local_position()[0] = meas.parameters()[Acts::eBoundLoc0]; + tm.local_position()[1] = 0.f; + tm.local_variance()[0] = meas.covariance()(0, 0); + tm.local_variance()[1] = 0.f; + tm.subspace()[0] = 0u; + tm.subspace()[1] = 1u; + nStripLong++; + } + } + + tm.surface_link() = detray::geometry::identifier(it->second); + tm.time() = 0.f; + tm.diameter() = 0.f; + tm.identifier() = static_cast(i); // store Acts index + tm.cluster_index() = 0u; + + ++nConverted; + } + + ACTS_INFO("ActsMeasToTracccAlg: converted " << nConverted << " / " + << actsMeasurements.size() + << " measurements"); + ACTS_INFO(" of which " << nPix << " pixel, " << nStripShort + << " short strip, " << nStripLong << " long strip"); + + ACTS_INFO("ActsMeasToTracccAlg: built " << tracccMeasurements.size() + << " measurements"); + + m_outputTracccMeasurements(ctx, std::move(tracccMeasurements)); + + return ProcessCode::SUCCESS; +} + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Traccc/src/ActsSpToTracccAlg.cpp b/Examples/Algorithms/Traccc/src/ActsSpToTracccAlg.cpp new file mode 100644 index 00000000000..72ebe91c257 --- /dev/null +++ b/Examples/Algorithms/Traccc/src/ActsSpToTracccAlg.cpp @@ -0,0 +1,63 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Traccc/ActsSpToTracccAlg.hpp" + +#include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/Framework/AlgorithmContext.hpp" + +#include + +namespace ActsExamples { + +ActsSpToTracccAlg::ActsSpToTracccAlg(const Config& cfg, + std::unique_ptr logger) + : IAlgorithm("ActsSpToTracccAlg", std::move(logger)), m_cfg(cfg) { + m_inputSpacePoints.initialize(m_cfg.inputSpacePoints); + m_outputTracccSpacepoints.initialize(m_cfg.outputTracccSpacepoints); +} + +ProcessCode ActsSpToTracccAlg::execute(const AlgorithmContext& ctx) const { + const auto& actsSpacePoints = m_inputSpacePoints(ctx); + + traccc::edm::spacepoint_collection::host tracccSpacepoints{m_mr}; + std::size_t nConverted = 0; + std::size_t nSkipped = 0; + + for (const auto& sp : actsSpacePoints) { + const auto sourceLinks = sp.sourceLinks(); + if (sourceLinks.empty()) { + ++nSkipped; + continue; + } + + // Get first source link — pixel or first strip of pair + const auto& sl1 = sourceLinks[0].get(); + const std::size_t tracccIdx1 = sl1.index(); + + tracccSpacepoints.push_back({}); + auto tsp = tracccSpacepoints.at(tracccSpacepoints.size() - 1); + tsp.measurement_index_1() = tracccIdx1; + tsp.global()[0] = sp.x(); + tsp.global()[1] = sp.y(); + tsp.global()[2] = sp.z(); + tsp.z_variance() = sp.varianceZ(); + tsp.radius_variance() = sp.varianceR(); + + ++nConverted; + } + + ACTS_INFO("ActsSpToTracccAlg: converted " + << nConverted << " / " << actsSpacePoints.size() << " spacepoints" + << " (skipped " << nSkipped << ")"); + + m_outputTracccSpacepoints(ctx, std::move(tracccSpacepoints)); + return ProcessCode::SUCCESS; +} + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Traccc/src/TracccChain.cpp b/Examples/Algorithms/Traccc/src/TracccChain.cpp new file mode 100644 index 00000000000..bd184d94397 --- /dev/null +++ b/Examples/Algorithms/Traccc/src/TracccChain.cpp @@ -0,0 +1,430 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Traccc/TracccChain.hpp" + +// ================================================================ +// Backend selection: ACTS_ENABLE_CUDA is set by the ACTS build +// system when -DACTS_ENABLE_CUDA=ON. No definition means CPU. +// ================================================================ + +#if defined(ACTS_ENABLE_CUDA) + +#include "traccc/cuda/ambiguity_resolution/greedy_ambiguity_resolution_algorithm.hpp" +#include "traccc/cuda/clusterization/clusterization_algorithm.hpp" +#include "traccc/cuda/clusterization/measurement_sorting_algorithm.hpp" +#include "traccc/cuda/finding/combinatorial_kalman_filter_algorithm.hpp" +#include "traccc/cuda/fitting/kalman_fitting_algorithm.hpp" +#include "traccc/cuda/seeding/seed_parameter_estimation_algorithm.hpp" +#include "traccc/cuda/seeding/silicon_pixel_spacepoint_formation_algorithm.hpp" +#include "traccc/cuda/seeding/triplet_seeding_algorithm.hpp" +#include "traccc/cuda/utils/make_magnetic_field.hpp" +#include "traccc/cuda/utils/stream.hpp" +#include "vecmem/memory/cuda/device_memory_resource.hpp" +#include "vecmem/memory/cuda/host_memory_resource.hpp" +#include "vecmem/memory/host_memory_resource.hpp" +#include "vecmem/utils/cuda/async_copy.hpp" + +#else // CPU + +#include "traccc/ambiguity_resolution/greedy_ambiguity_resolution_algorithm.hpp" +#include "traccc/clusterization/clusterization_algorithm.hpp" +#include "traccc/finding/combinatorial_kalman_filter_algorithm.hpp" +#include "traccc/fitting/kalman_fitting_algorithm.hpp" +#include "traccc/seeding/seeding_algorithm.hpp" +#include "traccc/seeding/silicon_pixel_spacepoint_formation_algorithm.hpp" +#include "traccc/seeding/track_params_estimation.hpp" +#include "vecmem/memory/host_memory_resource.hpp" +#include "vecmem/utils/copy.hpp" // FIX: was vecmem/utils/cuda/async_copy.hpp — wrong for CPU build + +#endif + +// traccc EDM +#include "traccc/edm/silicon_cell_collection.hpp" +#include "traccc/edm/spacepoint_collection.hpp" +#include "traccc/edm/track_collection.hpp" + +// traccc geometry + IO +#include "traccc/geometry/detector_buffer.hpp" +#include "traccc/geometry/detector_conditions_description.hpp" +#include "traccc/geometry/detector_design_description.hpp" +#include "traccc/geometry/host_detector.hpp" +#include "traccc/io/data_format.hpp" +#include "traccc/io/read_detector.hpp" +#include "traccc/io/read_detector_description.hpp" +#include "traccc/io/read_magnetic_field.hpp" + +// traccc magnetic field +#include "Acts/Utilities/Logger.hpp" + +#include "traccc/bfield/magnetic_field.hpp" + +namespace ActsExamples::Traccc { + +struct TracccChain::Impl { + std::unique_ptr m_logger; + const Acts::Logger& logger() const { return *m_logger; } + TracccChainConfig m_cfg; + + // ---- memory resources ---- + struct BaseMemory { + vecmem::copy* copy = nullptr; + vecmem::memory_resource* mr = nullptr; // host-accessible resource for IO + }; + struct HostMemory : public BaseMemory { + vecmem::host_memory_resource host_mr; + vecmem::copy host_copy; + HostMemory() : host_mr(), host_copy() { + copy = &host_copy; + mr = &host_mr; + } + }; +#if defined(ACTS_ENABLE_CUDA) + struct CudaMemory : public BaseMemory { + vecmem::cuda::host_memory_resource cuda_host_mr; + vecmem::cuda::device_memory_resource device_mr; + traccc::memory_resource mr_device{device_mr, &cuda_host_mr}; + traccc::cuda::stream stream; + vecmem::cuda::async_copy cuda_copy; + CudaMemory() + : cuda_host_mr(), + device_mr(), + stream(), + cuda_copy(stream.cudaStream()) { + copy = &cuda_copy; + mr = &cuda_host_mr; // host-pinned; usable by IO and host-side allocs + } + }; +#endif + + std::unique_ptr m_memory; + + // ---- detector description ---- + // unique_ptr: constructed in body once memory resource is known + std::unique_ptr m_det_descr; + std::unique_ptr m_det_cond; + traccc::host_detector m_host_detector; + + // Device-side copies — only populated for the CUDA backend + // you can imagine similar setup for HIP, Alpaka etc. +#if defined(ACTS_ENABLE_CUDA) + std::unique_ptr m_device_detector; + std::unique_ptr + m_device_det_descr; + std::unique_ptr + m_device_det_cond; +#endif + + // ---- magnetic field ---- + traccc::magnetic_field m_host_field; + traccc::vector3 + m_field_vec; // uniform approximation for CPU params estimation +#if defined(ACTS_ENABLE_CUDA) + traccc::magnetic_field m_device_field; +#endif + + // ---- algorithm objects (host / CPU) ---- + std::unique_ptr m_host_clusterization; + std::unique_ptr + m_host_spacepoint_formation; + std::unique_ptr m_host_seeding; + std::unique_ptr m_host_params_est; + std::unique_ptr + m_host_finding; + std::unique_ptr + m_host_ambiguity_resolution; + std::unique_ptr m_host_fitting; + + // ---- algorithm objects (device / CUDA) ---- +#if defined(ACTS_ENABLE_CUDA) + std::unique_ptr + m_device_clusterization; + std::unique_ptr + m_device_spacepoint_formation; + std::unique_ptr m_device_seeding; + std::unique_ptr< + traccc::algorithm> + m_device_params_est; + std::unique_ptr::buffer( + const traccc::detector_buffer&, const traccc::magnetic_field&, + const traccc::edm::measurement_collection::const_view&, + const traccc::bound_track_parameters_collection_types::const_view&)>> + m_device_finding; + std::unique_ptr::buffer( + const traccc::detector_buffer&, const traccc::magnetic_field&, + const traccc::edm::track_container< + traccc::default_algebra>::const_view&)>> + m_device_fitting; + // ambiguity resolution is not yet implemented on device +#endif + + // -------------------------------------------------------------- + explicit Impl(const TracccChainConfig& cfg, Acts::Logging::Level logLevel) + : m_logger(Acts::getDefaultLogger("TracccChain", logLevel)), m_cfg(cfg) { + if (cfg.backend == TracccChainConfig::Backend::CUDA) { +#if !defined(ACTS_ENABLE_CUDA) + throw std::runtime_error( + "TracccChainConfig requests CUDA backend but ACTS_ENABLE_CUDA is not " + "set"); +#else + ACTS_INFO("TracccChain configured to use CUDA backend"); + m_memory = std::make_unique(); + auto* cuda_mem = static_cast(m_memory.get()); + + m_det_descr = std::make_unique( + cuda_mem->cuda_host_mr); + m_det_cond = + std::make_unique( + cuda_mem->cuda_host_mr); + + m_device_clusterization = + std::make_unique( + cuda_mem->mr_device, cuda_mem->cuda_copy, cuda_mem->stream, + cfg.clusteringConfig, + Acts::getDefaultLogger("TracccClusterization", logLevel)); + m_device_spacepoint_formation = std::make_unique< + traccc::cuda::silicon_pixel_spacepoint_formation_algorithm>( + cuda_mem->mr_device, cuda_mem->cuda_copy, cuda_mem->stream, + Acts::getDefaultLogger("TracccSpFormation", logLevel)); + m_device_seeding = + std::make_unique( + cfg.seedfinderConfig, + traccc::spacepoint_grid_config{cfg.seedfinderConfig}, + cfg.seedfilterConfig, cuda_mem->mr_device, cuda_mem->cuda_copy, + cuda_mem->stream, + Acts::getDefaultLogger("TracccSeeding", logLevel)); + m_device_params_est = + std::make_unique( + cfg.trackParamsEstConfig, cuda_mem->mr_device, + cuda_mem->cuda_copy, cuda_mem->stream, + Acts::getDefaultLogger("TracccParamsEst", logLevel)); + m_device_finding = + std::make_unique( + cfg.findingConfig, cuda_mem->mr_device, cuda_mem->cuda_copy, + cuda_mem->stream, + Acts::getDefaultLogger("TracccFinding", logLevel)); + m_device_fitting = + std::make_unique( + cfg.fittingConfig, cuda_mem->mr_device, cuda_mem->cuda_copy, + cuda_mem->stream, + Acts::getDefaultLogger("TracccFitting", logLevel)); +#endif + } else { + ACTS_INFO("TracccChain configured to use CPU backend"); + m_memory = std::make_unique(); + auto* host_mem = static_cast(m_memory.get()); + + m_det_descr = std::make_unique( + host_mem->host_mr); + m_det_cond = + std::make_unique( + host_mem->host_mr); + + m_host_clusterization = + std::make_unique( + host_mem->host_mr, + Acts::getDefaultLogger("TracccClusterization", logLevel)); + m_host_spacepoint_formation = std::make_unique< + traccc::host::silicon_pixel_spacepoint_formation_algorithm>( + host_mem->host_mr, + Acts::getDefaultLogger("TracccSpFormation", logLevel)); + m_host_seeding = std::make_unique( + cfg.seedfinderConfig, + traccc::spacepoint_grid_config{cfg.seedfinderConfig}, + cfg.seedfilterConfig, host_mem->host_mr, + Acts::getDefaultLogger("TracccSeeding", logLevel)); + m_host_params_est = + std::make_unique( + cfg.trackParamsEstConfig, host_mem->host_mr, + Acts::getDefaultLogger("TracccParamsEst", logLevel)); + m_host_finding = + std::make_unique( + cfg.findingConfig, host_mem->host_mr, + Acts::getDefaultLogger("TracccFinding", logLevel)); + m_host_ambiguity_resolution = + std::make_unique( + cfg.resolutionConfig, host_mem->host_mr, + Acts::getDefaultLogger("TracccAmbiguity", logLevel)); + m_host_fitting = std::make_unique( + cfg.fittingConfig, host_mem->host_mr, *m_memory->copy, + Acts::getDefaultLogger("TracccFitting", logLevel)); + } + + // Load detector description + if (!cfg.digitizationFile.empty()) { + traccc::io::read_detector_description( + *m_det_descr, *m_det_cond, cfg.detectorFile, cfg.digitizationFile, + cfg.conditionsFile, traccc::data_format::json); + } + + // Load detector geometry — requires a host memory resource + traccc::io::read_detector(m_host_detector, *m_memory->mr, cfg.detectorFile, + cfg.materialFile, cfg.gridFile); + + // Load magnetic field + traccc::io::read_magnetic_field(m_host_field, cfg.magneticFieldFile); + m_field_vec = {0.f, 0.f, cfg.bFieldInZ}; + + if (cfg.backend == TracccChainConfig::Backend::CUDA) { +#if defined(ACTS_ENABLE_CUDA) + auto* cuda_mem = static_cast(m_memory.get()); + + m_device_field = traccc::cuda::make_magnetic_field( + m_host_field, traccc::cuda::magnetic_field_storage::global_memory); + + m_device_detector = std::make_unique( + traccc::buffer_from_host_detector( + m_host_detector, cuda_mem->device_mr, cuda_mem->cuda_copy)); + + std::vector descr_sizes(m_det_descr->size()); + for (std::size_t i = 0; i < m_det_descr->size(); ++i) { + auto design = m_det_descr->at(i); + descr_sizes[i] = + std::max(static_cast(design.bin_edges_x().size()), + static_cast(design.bin_edges_y().size())); + } + m_device_det_descr = + std::make_unique( + descr_sizes, cuda_mem->device_mr, &cuda_mem->cuda_host_mr, + vecmem::data::buffer_type::resizable); + + cuda_mem->copy->setup(*m_device_det_descr)->wait(); + cuda_mem->copy + ->operator()(vecmem::get_data(*m_det_descr), *m_device_det_descr) + ->wait(); + + m_device_det_cond = + std::make_unique( + static_cast< + traccc::detector_conditions_description::buffer::size_type>( + m_det_cond->size()), + cuda_mem->device_mr); + cuda_mem->copy->setup(*m_device_det_cond)->wait(); + cuda_mem->copy + ->operator()(vecmem::get_data(*m_det_cond), *m_device_det_cond) + ->wait(); + + cuda_mem->stream.synchronize(); +#endif + } + + ACTS_INFO( + "TracccChain initialised (" + << (cfg.backend == TracccChainConfig::Backend::CPU ? "CPU" : "CUDA") + << "\n" + << "), detector: " << cfg.detectorFile << "\n" + << ", digitization: " << cfg.digitizationFile << "\n" + << ", conditions: " << cfg.conditionsFile << "\n" + << ", material: " << cfg.materialFile << "\n" + << ", grid: " << cfg.gridFile << "\n" + << ", bfield: " << cfg.magneticFieldFile); + } + + // -------------------------------------------------------------- + EventResult run(traccc::edm::measurement_collection::host& meas_host, + traccc::edm::spacepoint_collection::host& sp_host) const { + EventResult result; + result.n_measurements = meas_host.size(); + result.n_spacepoints = sp_host.size(); + + ACTS_DEBUG("Running traccc chain with " + << meas_host.size() << " measurements and " << sp_host.size() + << " spacepoints."); + + if (m_cfg.backend != TracccChainConfig::Backend::CPU) { +#if defined(ACTS_ENABLE_CUDA) + auto* cuda_mem = static_cast(m_memory.get()); + + traccc::edm::measurement_collection::buffer meas_buf( + static_cast(meas_host.size()), cuda_mem->device_mr); + traccc::edm::spacepoint_collection::buffer sp_buf( + static_cast(sp_host.size()), cuda_mem->device_mr); + + cuda_mem->copy->setup(meas_buf)->wait(); + cuda_mem->copy->setup(sp_buf)->wait(); + cuda_mem->copy->operator()(vecmem::get_data(meas_host), meas_buf)->wait(); + cuda_mem->copy->operator()(vecmem::get_data(sp_host), sp_buf)->wait(); + + auto seeds_buf = (*m_device_seeding)(sp_buf); + result.n_seeds = cuda_mem->copy->get_size(seeds_buf); + + auto params_buf = + (*m_device_params_est)(m_device_field, meas_buf, sp_buf, seeds_buf); + + auto track_candidates_buf = (*m_device_finding)( + *m_device_detector, m_device_field, meas_buf, params_buf); + result.n_track_candidates = + cuda_mem->copy->get_size(track_candidates_buf.tracks); + + // No device ambiguity resolution yet — pass candidates directly to fitter + // if needed Fitting happened through MBF track finding + + // auto fitted_tracks_buf = (*m_device_fitting)( + // *m_device_detector, m_device_field, + // traccc::edm::track_container::const_view( + // track_candidates_buf)); + + // traccc::edm::track_container::host + // found_tracks_host; + // cuda_mem->copy->operator()(track_candidates_buf.tracks, + // found_tracks_host.tracks, + // vecmem::copy::type::device_to_host)->wait(); + // cuda_mem->copy->operator()(track_candidates_buf.states, + // found_tracks_host.states, + // vecmem::copy::type::device_to_host)->wait(); + // cuda_mem->stream.synchronize(); + + result.n_fitted_tracks = + cuda_mem->copy->get_size(track_candidates_buf.tracks); +#endif + } else { + // CPU execution + auto seeds_host = (*m_host_seeding)(vecmem::get_data(sp_host)); + result.n_seeds = seeds_host.size(); + + auto params_host = (*m_host_params_est)( + vecmem::get_data(meas_host), vecmem::get_data(sp_host), + vecmem::get_data(seeds_host), m_field_vec); + + auto track_candidates_host = (*m_host_finding)( + m_host_detector, m_host_field, vecmem::get_data(meas_host), + vecmem::get_data(params_host)); + result.n_track_candidates = track_candidates_host.tracks.size(); + + auto fitted_tracks_host = (*m_host_fitting)( + m_host_detector, m_host_field, + traccc::edm::track_container::const_data( + track_candidates_host)); + result.n_fitted_tracks = fitted_tracks_host.tracks.size(); + } + + return result; + } +}; + +TracccChain::TracccChain(const TracccChainConfig& cfg, + Acts::Logging::Level logLevel) + : m_impl(std::make_unique(cfg, logLevel)) {} + +TracccChain::~TracccChain() = default; +TracccChain::TracccChain(TracccChain&&) noexcept = default; +TracccChain& TracccChain::operator=(TracccChain&&) noexcept = default; + +EventResult TracccChain::operator()( + traccc::edm::measurement_collection::host& measurements, + traccc::edm::spacepoint_collection::host& spacepoints) const { + return m_impl->run(measurements, spacepoints); +} + +} // namespace ActsExamples::Traccc diff --git a/Examples/Algorithms/Traccc/src/TracccSeqAlg.cpp b/Examples/Algorithms/Traccc/src/TracccSeqAlg.cpp new file mode 100644 index 00000000000..f8c85c2dd99 --- /dev/null +++ b/Examples/Algorithms/Traccc/src/TracccSeqAlg.cpp @@ -0,0 +1,45 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Traccc/TracccSeqAlg.hpp" + +namespace ActsExamples::Traccc { + +TracccSeqAlg::TracccSeqAlg(const Config& cfg, + std::unique_ptr logger) + : IAlgorithm("TracccSeqAlg", std::move(logger)), + m_cfg(std::move(cfg)), + m_chain(m_cfg.chain, logger->level()) { + m_inputMeasurements.initialize(m_cfg.inputMeasurements); + m_inputSpacepoints.initialize(m_cfg.inputSpacepoints); +} + +ProcessCode TracccSeqAlg::execute(const AlgorithmContext& ctx) const { + const auto& measurements = m_inputMeasurements(ctx); + const auto& spacepoints = m_inputSpacepoints(ctx); + + ACTS_DEBUG("Running traccc chain on event " + << ctx.eventNumber << " with " << measurements.size() + << " measurements and " << spacepoints.size() << " spacepoints."); + + EventResult result = m_chain( + const_cast(measurements), + const_cast(spacepoints)); + + ACTS_INFO("Event information:"); + + ACTS_INFO("received " << result.n_measurements << " measurements,"); + ACTS_INFO("received " << result.n_spacepoints << " spacepoints,"); + ACTS_INFO("reconstructed " << result.n_seeds << " seeds,"); + ACTS_INFO("found " << result.n_track_candidates << " tracks,"); + ACTS_INFO("and fitted " << result.n_fitted_tracks << " tracks."); + + return ProcessCode::SUCCESS; +} + +} // namespace ActsExamples::Traccc diff --git a/Examples/Scripts/Python/full_chain_odd_traccc.py b/Examples/Scripts/Python/full_chain_odd_traccc.py new file mode 100644 index 00000000000..e30a1c3108a --- /dev/null +++ b/Examples/Scripts/Python/full_chain_odd_traccc.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python3 +""" +Full chain: ODD simulation → digitization → traccc GPU reconstruction +""" + +import pathlib +import argparse +import json + +import acts +import acts.examples + +from acts.examples.simulation import ( + MomentumConfig, + EtaConfig, + PhiConfig, + ParticleConfig, + addParticleGun, + addFatras, + addDigitization, +) +from acts.examples.odd import getOpenDataDetector, getOpenDataDetectorDirectory + +from acts.examples.traccc import ( + TracccSeqAlgorithm, + ActsSpToTracccAlg, + ActsMeasToTracccAlg, +) + +from acts.examples.simulation import ( + MomentumConfig, + EtaConfig, + PhiConfig, + ParticleConfig, + ParticleSelectorConfig, + addParticleGun, + addPythia8, + addGenParticleSelection, + addFatras, + addGeant4, + addSimParticleSelection, + addDigitization, + addDigiParticleSelection, +) + +u = acts.UnitConstants + + +def main(): + parser = argparse.ArgumentParser( + description="ODD simulation + traccc GPU reconstruction" + ) + parser.add_argument( + "--output", + "-o", + type=pathlib.Path, + default=pathlib.Path.cwd() / "traccc_full_output", + ) + parser.add_argument("--events", "-n", type=int, default=10) + parser.add_argument("--skip", type=int, default=0) + parser.add_argument("--gun-particles", type=int, default=4) + parser.add_argument("--gun-multiplicity", type=int, default=50) + parser.add_argument( + "--gun-pt-range", + nargs=2, + type=float, + default=[1.0, 10.0], + metavar=("PT_MIN", "PT_MAX"), + ) + parser.add_argument( + "--gun-eta-range", + nargs=2, + type=float, + default=[-3.0, 3.0], + metavar=("ETA_MIN", "ETA_MAX"), + ) + parser.add_argument("--detector-file", type=pathlib.Path, required=True) + parser.add_argument("--material-file", type=pathlib.Path, default=None) + parser.add_argument("--grid-file", type=pathlib.Path, default=None) + parser.add_argument("--material-map", type=pathlib.Path, default=None) + parser.add_argument("--digitization-file", type=pathlib.Path, required=True) + parser.add_argument("--bfield-file", type=pathlib.Path, required=True) + parser.add_argument("--conditions-file", type=pathlib.Path, default=True) + + parser.add_argument( + "--output-root", default=True, action=argparse.BooleanOptionalAction + ) + parser.add_argument( + "--output-csv", + help="Switch csv output on/off", + default=True, + action=argparse.BooleanOptionalAction, + ) + parser.add_argument( + "--log-level", + choices=["VERBOSE", "DEBUG", "INFO", "WARNING", "ERROR"], + default="INFO", + ) + parser.add_argument("--ttbar", action="store_true") + parser.add_argument("--ttbar-pu", type=int, default=200) + parser.add_argument("--geant4", action="store_true") + parser.add_argument("--do-cpu", action="store_true") + args = parser.parse_args() + + args.output.mkdir(parents=True, exist_ok=True) + logLevel = getattr(acts.logging, args.log_level) + + # ── Geometry ────────────────────────────────────────────────────────────── + geoDir = getOpenDataDetectorDirectory() + actsDir = pathlib.Path(__file__).parent.parent.parent.parent + + oddMaterialMap = geoDir / "data/odd-material-maps.root" + oddDigiConfig = actsDir / "Examples/Configs/odd-digi-smearing-config.json" + + oddMaterialDeco = acts.IMaterialDecorator.fromFile(oddMaterialMap) + detector = getOpenDataDetector(odd_dir=geoDir, materialDecorator=oddMaterialDeco) + trackingGeometry = detector.trackingGeometry() + field = acts.ConstantBField(acts.Vector3(0.0, 0.0, 2.0 * u.T)) + rnd = acts.examples.RandomNumbers(seed=42) + + # ── Sequencer ───────────────────────────────────────────────────────────── + s = acts.examples.Sequencer( + events=args.events, + skip=args.skip, + numThreads=1, + logLevel=logLevel, + outputDir=str(args.output), + trackFpes=False, + ) + + # ── Step 1: Simulation ──────────────────────────────────────────────────── + if args.ttbar: + addPythia8( + s, + hardProcess=["Top:qqbar2ttbar=on"], + npileup=args.ttbar_pu, + vtxGen=acts.examples.GaussianVertexGenerator( + mean=acts.Vector4(0, 0, 0, 0), + stddev=acts.Vector4( + 0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 5.0 * u.ns + ), + ), + rnd=rnd, + outputDirRoot=args.output if args.output_root else None, + outputDirCsv=args.output if args.output_csv else None, + ) + addGenParticleSelection( + s, + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + eta=(-3.0, 3.0), + pt=(150 * u.MeV, None), + ), + ) + else: + addParticleGun( + s, + MomentumConfig( + args.gun_pt_range[0] * u.GeV, + args.gun_pt_range[1] * u.GeV, + transverse=True, + ), + EtaConfig(args.gun_eta_range[0], args.gun_eta_range[1]), + PhiConfig(0.0, 360.0 * u.degree), + ParticleConfig( + args.gun_particles, acts.PdgParticle.eMuon, randomizeCharge=True + ), + vtxGen=acts.examples.GaussianVertexGenerator( + mean=acts.Vector4(0, 0, 0, 0), + stddev=acts.Vector4( + 0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 1.0 * u.ns + ), + ), + multiplicity=args.gun_multiplicity, + rnd=rnd, + ) + + if args.geant4: + if s.config.numThreads != 1: + raise ValueError("Geant4 does not support multi-threading") + addGeant4( + s, + detector, + trackingGeometry, + field, + outputDirRoot=args.output if args.output_root else None, + outputDirCsv=args.output if args.output_csv else None, + rnd=rnd, + killVolume=trackingGeometry.highestTrackingVolume, + killAfterTime=25 * u.ns, + ) + else: + addFatras( + s, + trackingGeometry, + field, + enableInteractions=True, + outputDirRoot=args.output if args.output_root else None, + outputDirCsv=args.output if args.output_csv else None, + rnd=rnd, + ) + + addSimParticleSelection( + s, + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + eta=(-3.0, 3.0), + removeNeutral=True, + ), + ) + + # ── Step 2: Digitization to Acts measurements ──────────────── + addDigitization( + s, + trackingGeometry, + field, + digiConfigFile=oddDigiConfig, + outputDirRoot=args.output if args.output_root else None, + rnd=rnd, + ) + + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), + ) + + # ── Step 3: Convert Acts measurements to traccc format ──────────────────── + m2tCfg = ActsMeasToTracccAlg.Config() + m2tCfg.inputActsMeasurements = "measurements" + m2tCfg.pixelVolumes = [16, 17, 18] # ODD Gen1 pixel volume IDs + m2tCfg.detectorFile = str(args.detector_file) + m2tCfg.outputDetrayToActsMap = "detray-to-acts-map" + m2tCfg.trackingGeometry = trackingGeometry + m2tCfg.outputTracccMeasurements = "acts-traccc-measurements" + s.addAlgorithm(ActsMeasToTracccAlg(m2tCfg, logLevel)) + + geoSelectionConfigFile = actsDir / "Examples/Configs/odd-seeding-config.json" + stripGeoSelectionConfigFile = "" + + spAlg = acts.examples.SpacePointMaker( + level=logLevel, + inputMeasurements=f"measurements", + outputSpacePoints=f"spacepoints", + trackingGeometry=trackingGeometry, + geometrySelection=acts.examples.json.readJsonGeometryList( + str(geoSelectionConfigFile) + ), + stripGeometrySelection=( + acts.examples.json.readJsonGeometryList(str(stripGeoSelectionConfigFile)) + if stripGeoSelectionConfigFile + else [] + ), + ) + s.addAlgorithm(spAlg) + + sp2tCfg = acts.examples.traccc.ActsSpToTracccAlg.Config() + sp2tCfg.inputSpacePoints = "spacepoints" + sp2tCfg.outputTracccSpacepoints = "acts-traccc-spacepoints" + s.addAlgorithm(acts.examples.traccc.ActsSpToTracccAlg(sp2tCfg, logLevel)) + + # ── Step 3.5: Write CSV files for Traccc standalone comparison ──────────────── + if args.output_csv: + s.addWriter( + acts.examples.CsvSpacePointWriter( + level=logLevel, + inputSpacePoints="spacepoints", + outputDir=str(args.output), + ) + ) + s.addWriter( + acts.examples.CsvMeasurementWriter( + level=logLevel, + inputMeasurements="measurements", + inputClusters="clusters", + inputMeasurementSimHitsMap="measurement_simhits_map", + outputDir=str(args.output), + ) + ) + + # ── Step 4: Run traccc GPU chain ────────────────────────────────────────── + seqCfg = TracccSeqAlgorithm.Config() + seqCfg.detectorFile = str(args.detector_file) + seqCfg.digitizationFile = str(args.digitization_file) + seqCfg.conditionsFile = str(args.conditions_file) + seqCfg.materialFile = str(args.material_file or pathlib.Path()) + seqCfg.gridFile = str(args.grid_file or pathlib.Path()) + seqCfg.bfieldFile = str(args.bfield_file) + seqCfg.inputMeasurements = "acts-traccc-measurements" + seqCfg.inputSpacepoints = "acts-traccc-spacepoints" + seqCfg.backend = ( + TracccSeqAlgorithm.Backend.CPU + if args.do_cpu + else TracccSeqAlgorithm.Backend.CUDA + ) + s.addAlgorithm(TracccSeqAlgorithm(seqCfg, logLevel)) + + s.run() + + +if __name__ == "__main__": + main() diff --git a/Plugins/CMakeLists.txt b/Plugins/CMakeLists.txt index e8fa5b5bace..9087e30fb84 100644 --- a/Plugins/CMakeLists.txt +++ b/Plugins/CMakeLists.txt @@ -11,6 +11,7 @@ add_component_if(Onnx PluginOnnx ACTS_BUILD_PLUGIN_ONNX) add_component_if(Gnn PluginGnn ACTS_BUILD_PLUGIN_GNN) add_component_if(Detray PluginDetray ACTS_BUILD_PLUGIN_TRACCC) add_component_if(Covfie PluginCovfie ACTS_BUILD_PLUGIN_TRACCC) +# add_component_if(Traccc PluginTraccc ACTS_BUILD_PLUGIN_TRACCC AND ACTS_ENABLE_CUDA) # dependent plugins. depend either on a independent plugins or on one another add_component_if(Root PluginRoot ACTS_BUILD_PLUGIN_ROOT) diff --git a/Plugins/Gnn/CMakeLists.txt b/Plugins/Gnn/CMakeLists.txt index bcc4916bdb5..a0fcb7f35f3 100644 --- a/Plugins/Gnn/CMakeLists.txt +++ b/Plugins/Gnn/CMakeLists.txt @@ -83,7 +83,7 @@ endif() if(ACTS_GNN_ENABLE_TORCH) target_compile_definitions(ActsPluginGnn PUBLIC ACTS_GNN_TORCH_BACKEND) target_link_libraries(ActsPluginGnn PRIVATE ${TORCH_LIBRARIES}) - if(ACTS_GNN_ENABLE_CUDA) + if(ACTS_ENABLE_CUDA) target_link_libraries(ActsPluginGnn PRIVATE frnn) endif() find_package(TorchScatter QUIET) diff --git a/Python/Examples/CMakeLists.txt b/Python/Examples/CMakeLists.txt index 35010485f47..069f08bb0c9 100644 --- a/Python/Examples/CMakeLists.txt +++ b/Python/Examples/CMakeLists.txt @@ -280,6 +280,13 @@ add_examples_binding_if( PLUGIN_IMPORT FALSE ) +add_examples_binding_if( + NAME Traccc + LINK_LIBRARIES Acts::ExamplesTraccc + FLAG ACTS_BUILD_PLUGIN_TRACCC + PLUGIN_IMPORT FALSE +) + # Special case for HepMC3 as it a hard dependency pybind11_add_module(ActsExamplesPythonBindingsHepMC3 src/plugins/HepMC3.cpp) install( diff --git a/Python/Examples/src/plugins/Traccc.cpp b/Python/Examples/src/plugins/Traccc.cpp new file mode 100644 index 00000000000..a357a2af506 --- /dev/null +++ b/Python/Examples/src/plugins/Traccc.cpp @@ -0,0 +1,127 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Traccc/ActsMeasToTracccAlg.hpp" +#include "ActsExamples/Traccc/ActsSpToTracccAlg.hpp" +#include "ActsExamples/Traccc/TracccChain.hpp" +#include "ActsExamples/Traccc/TracccSeqAlg.hpp" +#include "ActsPython/Utilities/Helpers.hpp" + +#include +#include + +namespace py = pybind11; +using namespace pybind11::literals; +using namespace ActsExamples; +using namespace ActsPython; + +PYBIND11_MODULE(ActsExamplesPythonBindingsTraccc, traccc) { + // ── TracccSeqAlg ───────────────────────────────────────────────────────── + { + using Alg = Traccc::TracccSeqAlg; + using Cfg = Alg::Config; + using ChainCfg = Traccc::TracccChainConfig; + + auto cls = + py::class_>( + traccc, "TracccSeqAlgorithm") + .def(py::init([](const Cfg& cfg, Acts::Logging::Level level) { + return std::make_shared( + cfg, Acts::getDefaultLogger("ActsMeasToTracccAlg", level)); + })); + + // auto cls = + // py::class_>( + // traccc, "TracccSeqAlgorithm") + // .def(py::init([](const Cfg& cfg, Acts::Logging::Level level) { + // return std::make_shared(cfg, level); + // }), + // "cfg"_a, "level"_a = Acts::Logging::INFO); + + py::enum_(traccc, "TracccBackend") + .value("CPU", ChainCfg::Backend::CPU) + .value("CUDA", ChainCfg::Backend::CUDA); + + cls.attr("Backend") = traccc.attr("TracccBackend"); + + py::class_(cls, "Config") + .def(py::init<>()) + // --- chain backend choice --- + .def_property( + "backend", [](const Cfg& c) { return c.chain.backend; }, + [](Cfg& c, ChainCfg::Backend v) { c.chain.backend = v; }) + // --- chain inputs --- + .def_property( + "detectorFile", [](const Cfg& c) { return c.chain.detectorFile; }, + [](Cfg& c, const std::string& v) { c.chain.detectorFile = v; }) + .def_property( + "digitizationFile", + [](const Cfg& c) { return c.chain.digitizationFile; }, + [](Cfg& c, const std::string& v) { c.chain.digitizationFile = v; }) + .def_property( + "conditionsFile", + [](const Cfg& c) { return c.chain.conditionsFile; }, + [](Cfg& c, const std::string& v) { c.chain.conditionsFile = v; }) + .def_property( + "materialFile", [](const Cfg& c) { return c.chain.materialFile; }, + [](Cfg& c, const std::string& v) { c.chain.materialFile = v; }) + .def_property( + "gridFile", [](const Cfg& c) { return c.chain.gridFile; }, + [](Cfg& c, const std::string& v) { c.chain.gridFile = v; }) + .def_property( + "bfieldFile", + [](const Cfg& c) { return c.chain.magneticFieldFile; }, + [](Cfg& c, const std::string& v) { c.chain.magneticFieldFile = v; }) + // --- direct input --- + .def_readwrite("inputMeasurements", &Cfg::inputMeasurements) + .def_readwrite("inputSpacepoints", &Cfg::inputSpacepoints); + } + + // ── ActsMeasToTracccAlg ─────────────────────────────────────────────────── + { + using Alg = ActsExamples::ActsMeasToTracccAlg; + using Cfg = Alg::Config; + + auto cls = + py::class_>( + traccc, "ActsMeasToTracccAlg") + .def(py::init([](const Cfg& cfg, Acts::Logging::Level level) { + return std::make_shared( + cfg, Acts::getDefaultLogger("ActsMeasToTracccAlg", level)); + })); + + py::class_(cls, "Config") + .def(py::init<>()) + .def_readwrite("detectorFile", &Cfg::detectorFile) + .def_readwrite("inputActsMeasurements", &Cfg::inputActsMeasurements) + .def_readwrite("outputDetrayToActsMap", &Cfg::outputDetrayToActsMap) + .def_readwrite("outputTracccMeasurements", + &Cfg::outputTracccMeasurements) + .def_readwrite("trackingGeometry", &Cfg::trackingGeometry); + } + + // ── ActsSpToTracccAlg ───────────────────────────────────────────────────── + { + using Alg = ActsExamples::ActsSpToTracccAlg; + using Cfg = Alg::Config; + + auto cls = + py::class_>( + traccc, "ActsSpToTracccAlg") + .def(py::init([](const Cfg& cfg, Acts::Logging::Level level) { + return std::make_shared( + cfg, Acts::getDefaultLogger("ActsSpToTracccAlg", level)); + })); + + py::class_(cls, "Config") + .def(py::init<>()) + .def_readwrite("inputSpacePoints", &Cfg::inputSpacePoints) + .def_readwrite("outputTracccSpacepoints", + &Cfg::outputTracccSpacepoints); + } +} diff --git a/cmake/ActsExternSources.cmake b/cmake/ActsExternSources.cmake index 402ec94a717..be76f3f1492 100644 --- a/cmake/ActsExternSources.cmake +++ b/cmake/ActsExternSources.cmake @@ -20,7 +20,7 @@ set(ACTS_COVFIE_SOURCE mark_as_advanced(ACTS_COVFIE_SOURCE) set(ACTS_TRACCC_SOURCE - "URL;https://github.com/acts-project/traccc/archive/refs/tags/v${_acts_traccc_version}.tar.gz;URL_HASH;SHA256=de4c88028f51deb63d75c5bdcde40803832e372219cd59d195a748560dacdeb1" + "GIT_REPOSITORY;https://github.com/acts-project/traccc.git;GIT_TAG;origin/main" CACHE STRING "Source to take TRACCC from" ) diff --git a/docs/old/getting_started.md b/docs/old/getting_started.md index 2b28214e0f4..a918b7f6ae3 100644 --- a/docs/old/getting_started.md +++ b/docs/old/getting_started.md @@ -284,11 +284,11 @@ components. | ACTS_BUILD_PLUGIN_FPEMON | Build FPE monitoring plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GEOMODEL | Build GeoModel plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_TRACCC | Build Traccc plugin
type: `bool`, default: `OFF` | +| ACTS_ENABLE_CUDA | Enable CUDA for the gnn/Traccc plugins
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GEANT4 | Build Geant4 plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GNN | Build the GNN plugin
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_ONNX | Build the Onnx backend for the gnn
plugin
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_TORCH | Build the torchscript backend for the
gnn plugin
type: `bool`, default: `ON` | -| ACTS_GNN_ENABLE_CUDA | Enable CUDA for the gnn plugin
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_MODULEMAP | Enable Module-Map-based graph
construction
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_TENSORRT | Enable the native TensorRT inference
modules
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_JSON | Build json plugin
type: `bool`, default: `OFF` | diff --git a/docs/pages/contributing/building_acts.md b/docs/pages/contributing/building_acts.md index 8cf6cd15ec0..c6da7269998 100644 --- a/docs/pages/contributing/building_acts.md +++ b/docs/pages/contributing/building_acts.md @@ -272,11 +272,12 @@ components. | ACTS_BUILD_PLUGIN_FPEMON | Build FPE monitoring plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GEOMODEL | Build GeoModel plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_TRACCC | Build Traccc plugin
type: `bool`, default: `OFF` | +| ACTS_ENABLE_CUDA | Enable CUDA for the gnn/Traccc plugins
type: `bool`, default: `OFF` | +| ACTS_GNN_ENABLE_CUDA | [Deprecated] Enable CUDA for the gnn
plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GEANT4 | Build Geant4 plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GNN | Build the GNN plugin
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_ONNX | Build the Onnx backend for the gnn
plugin
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_TORCH | Build the torchscript backend for the
gnn plugin
type: `bool`, default: `ON` | -| ACTS_GNN_ENABLE_CUDA | Enable CUDA for the gnn plugin
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_MODULEMAP | Enable Module-Map-based graph
construction
type: `bool`, default: `OFF` | | ACTS_GNN_ENABLE_TENSORRT | Enable the native TensorRT inference
modules
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_JSON | Build json plugin
type: `bool`, default: `OFF` | diff --git a/thirdparty/traccc/CMakeLists.txt b/thirdparty/traccc/CMakeLists.txt index 203cf98c451..52228a48191 100644 --- a/thirdparty/traccc/CMakeLists.txt +++ b/thirdparty/traccc/CMakeLists.txt @@ -19,22 +19,16 @@ set(TRACCC_VERSION "${_acts_traccc_version}") # Declare where to get traccc from. FetchContent_Declare(traccc SYSTEM ${ACTS_TRACCC_SOURCE}) -set(ACTS_TRACCC_SCALARTYPE "double") - set(TRACCC_CUSTOM_SCALARTYPE - "${ACTS_TRACCC_SCALARTYPE}" + "float" CACHE STRING "Scalar type to use in the traccc code" ) -set(TRACCC_SETUP_VECMEM OFF CACHE BOOL "Do not set up Actsvg as part of Traccc") +set(TRACCC_SETUP_VECMEM OFF CACHE BOOL "Do not set up VecMem as part of Traccc") set(TRACCC_SETUP_EIGEN3 OFF CACHE BOOL "Do not set up Eigen3 as part of Traccc") set(TRACCC_SETUP_THRUST ON CACHE BOOL "Do not set up Thrust as part of Traccc") -set(TRACCC_SETUP_ALGEBRA_PLUGINS - OFF - CACHE BOOL - "Do not set up Algebra Plugins as part of Traccc" -) + set(TRACCC_SETUP_COVFIE OFF CACHE BOOL "Do not set up Covfie as part of Traccc") set(TRACCC_SETUP_DFELIBS ON @@ -43,29 +37,46 @@ set(TRACCC_SETUP_DFELIBS ) set(TRACCC_SETUP_DETRAY OFF CACHE BOOL "Set up Detray as part of Traccc") set(TRACCC_SETUP_ACTS OFF CACHE BOOL "Do not set up ACTS as part of Traccc") -set(TRACCC_SETUP_TBB OFF CACHE BOOL "Do not set up TBB as part of Traccc") -set(TRACCC_SETUP_BENCHMARKS - OFF + +set(TRACCC_BUILD_CUDA + ${ACTS_ENABLE_CUDA} CACHE BOOL - "Do not set up google benchmarks as part of Traccc" + "Build Traccc with CUDA support" ) set(TRACCC_BUILD_IO - OFF + ON CACHE BOOL "Turn off the build of the Traccc IO code THIS IS TEMPORARY" ) +set(TRACCC_BUILD_PERFORMANCE + OFF + CACHE BOOL + "Turn off the build of the Traccc performance code" +) + +set(TRACCC_BUILD_SIMULATION + OFF + CACHE BOOL + "Turn off the build of the Traccc simulation code" +) + set(TRACCC_BUILD_TESTING OFF CACHE BOOL "Turn off the build of the Traccc unit tests" ) + +set(TRACCC_SETUP_TBB OFF CACHE BOOL "Do not set up TBB as part of Traccc") +set(TRACCC_USE_SYSTEM_TBB ON CACHE BOOL "Use the system TBB for Traccc") + set(TRACCC_BUILD_EXAMPLES OFF CACHE BOOL "Turn off the build of the Traccc examples" ) + set(TRACCC_BUILD_BENCHMARKS OFF CACHE BOOL diff --git a/thirdparty/vecmem/CMakeLists.txt b/thirdparty/vecmem/CMakeLists.txt index 76974e9916d..471bb7af1ee 100644 --- a/thirdparty/vecmem/CMakeLists.txt +++ b/thirdparty/vecmem/CMakeLists.txt @@ -31,5 +31,7 @@ set(VECMEM_BUILD_BENCHMARKING "Turn off the build of VecMem benchmarking" ) +set_option_if(VECMEM_BUILD_CUDA_LIBRARY ACTS_ENABLE_CUDA) + # Now set up its build. FetchContent_MakeAvailable(VecMem)