From cf668d492a854533c53052f9d76cb735ae6a5498 Mon Sep 17 00:00:00 2001 From: Christoph Hasse <christoph.hasse@cern.ch> Date: Thu, 27 May 2021 14:05:23 +0200 Subject: [PATCH] refactor: removed unsed SOA{Container,Extension} --- .gitmodules | 3 - CMakeLists.txt | 1 + Event/EventBase/CMakeLists.txt | 5 +- Event/EventBase/Event/SOACollection.h | 2 +- Event/EventBase/Event/Zip.h | 2 +- .../EventBase/Event}/ZipUtils.h | 8 +- Event/EventBase/tests/src/test_STL.cpp | 1 - Event/RecEvent/CMakeLists.txt | 8 +- Event/RecEvent/Event/MuonPID_v2.h | 8 - Event/RecEvent/Event/TrackWithMuonPIDSkin.h | 20 - .../tests/src/TestMuonZipInfrastructure.cpp | 3 - Event/TrackEvent/CMakeLists.txt | 6 +- Event/TrackEvent/Event/PrDownstreamTracks.h | 1 - .../TrackEvent/Event/PrFittedForwardTracks.h | 1 - Event/TrackEvent/Event/PrLongTracks.h | 1 - Event/TrackEvent/Event/PrUTHits.h | 1 - Event/TrackEvent/Event/PrUpstreamTracks.h | 1 - Event/TrackEvent/Event/PrVeloHits.h | 1 - Event/TrackEvent/Event/PrVeloTracks.h | 1 - Event/TrackEvent/Event/TrackSkin.h | 45 -- Event/TrackEvent/Event/Track_SOA.h | 1 - Kernel/SOAContainer/CMakeLists.txt | 36 -- Kernel/SOAContainer/SOAContainer | 1 - .../submodules/.gaudi_project_ignore | 1 - Kernel/SOAExtensions/CMakeLists.txt | 61 -- .../SOAExtensions/IncompatibleZipException.h | 37 -- .../SOAExtensions/ZipAlgorithms.h | 270 --------- .../SOAExtensions/ZipContainer.h | 196 ------- .../SOAExtensions/ZipSelection.h | 543 ------------------ .../SOAExtensions/SOAExtensions/ZipTraits.h | 63 -- .../examples/options/BarrierExamples.py | 176 ------ .../examples/options/apples_1.py | 36 -- Kernel/SOAExtensions/examples/src/Print.cpp | 96 ---- .../SOAExtensions/examples/src/Producer.cpp | 49 -- Kernel/SOAExtensions/examples/src/Select.cpp | 54 -- .../SOAExtensions/examples/src/Transform.cpp | 43 -- Kernel/SOAExtensions/examples/src/apples.cpp | 390 ------------- .../examples/src/barrier_types.h | 85 --- Kernel/SOAExtensions/examples/src/classes.cpp | 14 - Kernel/SOAExtensions/examples/src/classes.h | 322 ----------- .../SOAExtensions/src/ZipBarrierGatherer.cpp | 50 -- Kernel/SOAExtensions/src/ZipBarrierMerger.cpp | 85 --- .../tests/qmtest/soaextensions.qms/apples.qmt | 28 - .../qmtest/soaextensions.qms/barrier.qmt | 28 - .../SOAExtensions/tests/src/TestSelection.cpp | 292 ---------- .../tests/src/hana_soa_access.cpp | 104 ---- 46 files changed, 12 insertions(+), 3168 deletions(-) delete mode 100644 .gitmodules rename {Kernel/SOAExtensions/SOAExtensions => Event/EventBase/Event}/ZipUtils.h (97%) delete mode 100644 Event/RecEvent/Event/TrackWithMuonPIDSkin.h delete mode 100644 Event/TrackEvent/Event/TrackSkin.h delete mode 100644 Kernel/SOAContainer/CMakeLists.txt delete mode 120000 Kernel/SOAContainer/SOAContainer delete mode 100644 Kernel/SOAContainer/submodules/.gaudi_project_ignore delete mode 100644 Kernel/SOAExtensions/CMakeLists.txt delete mode 100644 Kernel/SOAExtensions/SOAExtensions/IncompatibleZipException.h delete mode 100644 Kernel/SOAExtensions/SOAExtensions/ZipAlgorithms.h delete mode 100644 Kernel/SOAExtensions/SOAExtensions/ZipContainer.h delete mode 100644 Kernel/SOAExtensions/SOAExtensions/ZipSelection.h delete mode 100644 Kernel/SOAExtensions/SOAExtensions/ZipTraits.h delete mode 100644 Kernel/SOAExtensions/examples/options/BarrierExamples.py delete mode 100644 Kernel/SOAExtensions/examples/options/apples_1.py delete mode 100644 Kernel/SOAExtensions/examples/src/Print.cpp delete mode 100644 Kernel/SOAExtensions/examples/src/Producer.cpp delete mode 100644 Kernel/SOAExtensions/examples/src/Select.cpp delete mode 100644 Kernel/SOAExtensions/examples/src/Transform.cpp delete mode 100644 Kernel/SOAExtensions/examples/src/apples.cpp delete mode 100644 Kernel/SOAExtensions/examples/src/barrier_types.h delete mode 100644 Kernel/SOAExtensions/examples/src/classes.cpp delete mode 100644 Kernel/SOAExtensions/examples/src/classes.h delete mode 100644 Kernel/SOAExtensions/src/ZipBarrierGatherer.cpp delete mode 100644 Kernel/SOAExtensions/src/ZipBarrierMerger.cpp delete mode 100644 Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/apples.qmt delete mode 100644 Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/barrier.qmt delete mode 100644 Kernel/SOAExtensions/tests/src/TestSelection.cpp delete mode 100644 Kernel/SOAExtensions/tests/src/hana_soa_access.cpp diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index c34bbba71b0..00000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "Kernel/SOAContainer/submodules/SOAContainer"] - path = Kernel/SOAContainer/submodules/SOAContainer - url = https://gitlab.cern.ch/LHCbOpt/SOAContainer.git diff --git a/CMakeLists.txt b/CMakeLists.txt index c11426b3249..fafead9506a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ # or submit itself to any jurisdiction. # ############################################################################### CMAKE_MINIMUM_REQUIRED(VERSION 3.15) +set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) #--------------------------------------------------------------- # Load macros and functions for Gaudi-based projects diff --git a/Event/EventBase/CMakeLists.txt b/Event/EventBase/CMakeLists.txt index 3b60c5b3454..ec75e7d91e2 100644 --- a/Event/EventBase/CMakeLists.txt +++ b/Event/EventBase/CMakeLists.txt @@ -14,8 +14,7 @@ gaudi_subdir(EventBase) gaudi_depends_on_subdirs(GaudiKernel - Kernel/LHCbKernel - Kernel/SOAExtensions) + Kernel/LHCbKernel) gaudi_install_headers(Event) @@ -23,7 +22,7 @@ gaudi_add_dictionary(EventBase dict/dictionary.h dict/selection.xml LINK_LIBRARI gaudi_add_unit_test(test_SOACollection tests/src/test_SOACollection.cpp - INCLUDE_DIRS EventBase Kernel/SOAExtensions + INCLUDE_DIRS EventBase LINK_LIBRARIES GaudiKernel TYPE Boost) gaudi_add_unit_test(test_ZipSTL tests/src/test_STL.cpp diff --git a/Event/EventBase/Event/SOACollection.h b/Event/EventBase/Event/SOACollection.h index 50e0de751a2..b54d9abb9a8 100644 --- a/Event/EventBase/Event/SOACollection.h +++ b/Event/EventBase/Event/SOACollection.h @@ -11,8 +11,8 @@ #pragma once #include "Kernel/EventLocalAllocator.h" #include "Kernel/STLExtensions.h" -#include "SOAExtensions/ZipUtils.h" #include "SOAUtils.h" +#include "ZipUtils.h" #include <boost/align/is_aligned.hpp> #include <boost/integer/common_factor_rt.hpp> diff --git a/Event/EventBase/Event/Zip.h b/Event/EventBase/Event/Zip.h index bcfedd75ce6..face37bd3c6 100644 --- a/Event/EventBase/Event/Zip.h +++ b/Event/EventBase/Event/Zip.h @@ -13,7 +13,7 @@ #include "GaudiKernel/detected.h" #include "Kernel/HeaderMapping.h" #include "LHCbMath/SIMDWrapper.h" -#include "SOAExtensions/ZipUtils.h" +#include "ZipUtils.h" #include <boost/mp11/algorithm.hpp> #include <boost/mp11/bind.hpp> diff --git a/Kernel/SOAExtensions/SOAExtensions/ZipUtils.h b/Event/EventBase/Event/ZipUtils.h similarity index 97% rename from Kernel/SOAExtensions/SOAExtensions/ZipUtils.h rename to Event/EventBase/Event/ZipUtils.h index 9fa062410ac..387043beb01 100644 --- a/Kernel/SOAExtensions/SOAExtensions/ZipUtils.h +++ b/Event/EventBase/Event/ZipUtils.h @@ -21,18 +21,15 @@ * @author Paul Seyfert Paul.Seyfert@cern.ch * @date 2019-02-22 */ -#ifndef ZipUtils_H -#define ZipUtils_H 1 +#pragma once + #ifndef NDEBUG # define ZIPPING_SEMANTIC_CHECKS #else // Comment out to disable runtime checks in optimised builds # define ZIPPING_SEMANTIC_CHECKS #endif -#include "SOAContainer/SOAUtils.h" -#include "ZipTraits.h" // IWYU pragma: keep -#include "GaudiKernel/GaudiException.h" #include "GaudiKernel/Kernel.h" #include <atomic> @@ -163,4 +160,3 @@ namespace Zipping { } } // namespace Zipping -#endif diff --git a/Event/EventBase/tests/src/test_STL.cpp b/Event/EventBase/tests/src/test_STL.cpp index c2eaed431e0..55e43e2a532 100644 --- a/Event/EventBase/tests/src/test_STL.cpp +++ b/Event/EventBase/tests/src/test_STL.cpp @@ -12,7 +12,6 @@ #include "Event/Zip.h" #include "GaudiKernel/GaudiException.h" #include "LHCbMath/SIMDWrapper.h" -#include "SOAExtensions/ZipUtils.h" #include <algorithm> #include <numeric> diff --git a/Event/RecEvent/CMakeLists.txt b/Event/RecEvent/CMakeLists.txt index 8526113ee07..30bf7e18034 100644 --- a/Event/RecEvent/CMakeLists.txt +++ b/Event/RecEvent/CMakeLists.txt @@ -18,17 +18,15 @@ gaudi_depends_on_subdirs(Event/DigiEvent Event/TrackEvent Kernel/LHCbKernel Kernel/LHCbMath - Kernel/PartProp - Kernel/SOAContainer - Kernel/SOAExtensions) + Kernel/PartProp) gaudi_add_library(RecEvent src/*.cpp PUBLIC_HEADERS Event Interfaces - INCLUDE_DIRS Event/DigiEvent Event/EventBase Kernel/SOAContainer Kernel/SOAExtensions + INCLUDE_DIRS Event/DigiEvent Event/EventBase LINK_LIBRARIES TrackEvent LHCbMathLib PartPropLib) -gaudi_add_dictionary(RecEvent dict/dictionary.h dict/selection.xml LINK_LIBRARIES LHCbKernel LHCbMathLib PartPropLib RecEvent TrackEvent INCLUDE_DIRS Event/DigiEvent Event/EventBase Kernel/SOAContainer) +gaudi_add_dictionary(RecEvent dict/dictionary.h dict/selection.xml LINK_LIBRARIES LHCbKernel LHCbMathLib PartPropLib RecEvent TrackEvent INCLUDE_DIRS Event/DigiEvent Event/EventBase) gaudi_add_unit_test(TestMuonZipInfrastructure tests/src/TestMuonZipInfrastructure.cpp diff --git a/Event/RecEvent/Event/MuonPID_v2.h b/Event/RecEvent/Event/MuonPID_v2.h index e5423d24b6a..ae32e2bbd3f 100644 --- a/Event/RecEvent/Event/MuonPID_v2.h +++ b/Event/RecEvent/Event/MuonPID_v2.h @@ -12,8 +12,6 @@ #define RecEvent_MuonPID_v2_H 1 // Include files -#include "SOAContainer/SOAField.h" -#include "SOAContainer/SOASkin.h" #include <ostream> #include <vector> @@ -130,12 +128,6 @@ namespace LHCb::Event::v2 { }; // class MuonPID - // clang-format off - SOAFIELD( MuonPIDField, MuonPID, SOAFIELD_ACCESSORS( muonPID ) - auto IsMuon() const { return muonPID().IsMuon(); } - ); - // clang-format on - SOASKIN_TRIVIAL( MuonID, MuonPIDField ); } // namespace LHCb::Event::v2 #endif diff --git a/Event/RecEvent/Event/TrackWithMuonPIDSkin.h b/Event/RecEvent/Event/TrackWithMuonPIDSkin.h deleted file mode 100644 index a0f87467ffe..00000000000 --- a/Event/RecEvent/Event/TrackWithMuonPIDSkin.h +++ /dev/null @@ -1,20 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ -#pragma once -#include "Event/MuonPID_v2.h" -#include "Event/TrackSkin.h" -#include "SOAContainer/SOAField.h" -#include "SOAContainer/SOASkin.h" - -namespace LHCb::Event::v2 { - // Define a type for zipping together track and muonID objects - SOASKIN_TRIVIAL( TrackWithMuonID, TrackField, MuonPIDField ); -} // namespace LHCb::Event::v2 diff --git a/Event/RecEvent/tests/src/TestMuonZipInfrastructure.cpp b/Event/RecEvent/tests/src/TestMuonZipInfrastructure.cpp index 5e0d8afa852..02f7df1b66b 100644 --- a/Event/RecEvent/tests/src/TestMuonZipInfrastructure.cpp +++ b/Event/RecEvent/tests/src/TestMuonZipInfrastructure.cpp @@ -9,14 +9,11 @@ * or submit itself to any jurisdiction. * \*****************************************************************************/ #include "Event/GeneratePrFittedForwardTracks.h" -#include "Event/MuonPID_v2.h" #include "Event/PrFittedForwardTracks.h" #include "Event/PrMuonPIDs.h" #include "Event/StateParameters.h" #include "Event/Zip.h" #include "GaudiKernel/SerializeSTL.h" -#include "SOAExtensions/ZipAlgorithms.h" -#include "SOAExtensions/ZipUtils.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE utestZipInfrastructure diff --git a/Event/TrackEvent/CMakeLists.txt b/Event/TrackEvent/CMakeLists.txt index 918aa95c908..06b0f5214e3 100644 --- a/Event/TrackEvent/CMakeLists.txt +++ b/Event/TrackEvent/CMakeLists.txt @@ -14,9 +14,7 @@ gaudi_subdir(TrackEvent) gaudi_depends_on_subdirs(Kernel/LHCbKernel - Kernel/SOAContainer - Event/EventBase - Kernel/SOAExtensions) + Event/EventBase) find_package(Boost) find_package(GSL) @@ -28,7 +26,7 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS}) gaudi_add_library(TrackEvent src/*.cpp PUBLIC_HEADERS Event - INCLUDE_DIRS GSL Boost Rangev3 Kernel/SOAContainer Kernel/SOAExtensions + INCLUDE_DIRS GSL Boost Rangev3 LINK_LIBRARIES GSL Boost LHCbKernel ) gaudi_add_unit_test(test_deref tests/src/test_deref.cpp diff --git a/Event/TrackEvent/Event/PrDownstreamTracks.h b/Event/TrackEvent/Event/PrDownstreamTracks.h index 372d47434b7..a4527697216 100644 --- a/Event/TrackEvent/Event/PrDownstreamTracks.h +++ b/Event/TrackEvent/Event/PrDownstreamTracks.h @@ -21,7 +21,6 @@ #include "LHCbMath/bit_cast.h" #include "PrSeedTracks.h" #include "PrTracksTag.h" -#include "SOAExtensions/ZipUtils.h" /** * Downstream track made with a FT seed and UT hits diff --git a/Event/TrackEvent/Event/PrFittedForwardTracks.h b/Event/TrackEvent/Event/PrFittedForwardTracks.h index 075b0a06310..8e585473823 100644 --- a/Event/TrackEvent/Event/PrFittedForwardTracks.h +++ b/Event/TrackEvent/Event/PrFittedForwardTracks.h @@ -18,7 +18,6 @@ #include "Kernel/LHCbID.h" #include "LHCbMath/SIMDWrapper.h" #include "LHCbMath/Vec3.h" -#include "SOAExtensions/ZipUtils.h" /** * Track data after the Kalman fit diff --git a/Event/TrackEvent/Event/PrLongTracks.h b/Event/TrackEvent/Event/PrLongTracks.h index 7550c9cfdfb..4c772a0ba8d 100644 --- a/Event/TrackEvent/Event/PrLongTracks.h +++ b/Event/TrackEvent/Event/PrLongTracks.h @@ -22,7 +22,6 @@ #include "Kernel/VPChannelID.h" #include "LHCbMath/SIMDWrapper.h" #include "LHCbMath/Vec3.h" -#include "SOAExtensions/ZipUtils.h" /** * Track data for exchanges between FT and Fit diff --git a/Event/TrackEvent/Event/PrUTHits.h b/Event/TrackEvent/Event/PrUTHits.h index 9f5721fe6c0..10338475063 100644 --- a/Event/TrackEvent/Event/PrUTHits.h +++ b/Event/TrackEvent/Event/PrUTHits.h @@ -14,7 +14,6 @@ #include "Kernel/EventLocalAllocator.h" #include "LHCbMath/SIMDWrapper.h" #include "PrTracksTag.h" -#include "SOAExtensions/ZipUtils.h" /** @class PrUTHits PrUTHits.h * SoA Implementation of Upstream tracker hit for pattern recognition diff --git a/Event/TrackEvent/Event/PrUpstreamTracks.h b/Event/TrackEvent/Event/PrUpstreamTracks.h index 14b169cb284..1354f89726e 100644 --- a/Event/TrackEvent/Event/PrUpstreamTracks.h +++ b/Event/TrackEvent/Event/PrUpstreamTracks.h @@ -21,7 +21,6 @@ #include "LHCbMath/bit_cast.h" #include "PrTracksTag.h" #include "PrVeloTracks.h" -#include "SOAExtensions/ZipUtils.h" /** * diff --git a/Event/TrackEvent/Event/PrVeloHits.h b/Event/TrackEvent/Event/PrVeloHits.h index 05e6a6519c0..84410959a94 100644 --- a/Event/TrackEvent/Event/PrVeloHits.h +++ b/Event/TrackEvent/Event/PrVeloHits.h @@ -15,7 +15,6 @@ #include "LHCbMath/SIMDWrapper.h" #include "LHCbMath/Vec3.h" #include "PrTracksTag.h" -#include "SOAExtensions/ZipUtils.h" /** * Hits in VP diff --git a/Event/TrackEvent/Event/PrVeloTracks.h b/Event/TrackEvent/Event/PrVeloTracks.h index 6787aba5374..28a25be7aad 100644 --- a/Event/TrackEvent/Event/PrVeloTracks.h +++ b/Event/TrackEvent/Event/PrVeloTracks.h @@ -22,7 +22,6 @@ #include "LHCbMath/SIMDWrapper.h" #include "LHCbMath/Vec3.h" #include "PrTracksTag.h" -#include "SOAExtensions/ZipUtils.h" /** * Track data for exchanges between VeloTracking and UT diff --git a/Event/TrackEvent/Event/TrackSkin.h b/Event/TrackEvent/Event/TrackSkin.h deleted file mode 100644 index 219cef00ddb..00000000000 --- a/Event/TrackEvent/Event/TrackSkin.h +++ /dev/null @@ -1,45 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ - -#pragma once - -// Include files -#include "Event/Track_v2.h" -#include "SOAContainer/SOAField.h" -#include "SOAContainer/SOASkin.h" - -namespace LHCb::Event::v2 { - // clang-format off - SOAFIELD( TrackField, Track, SOAFIELD_ACCESSORS( track ) - auto p() const { return track().p(); } - auto pt() const { return track().pt(); } - auto pseudoRapidity() const { return track().pseudoRapidity(); } - auto chi2PerDoF() const { return track().chi2PerDoF(); } - template <typename... Args> - auto stateAt( Args&&... args ) const { - return track().stateAt( std::forward<Args>( args )... ); - } - decltype( auto ) closestToBeamState() const { - return track().closestToBeamState(); - } - decltype( auto ) endScifiState() const { - return track().endScifiState(); - } - decltype( auto ) closestToBeamStatePos() const { - return closestToBeamState().position(); - } - decltype( auto ) closestToBeamStateDir() const { - return closestToBeamState().slopes(); - } - ); - // clang-format on - SOASKIN_TRIVIAL( TrackSkin, TrackField ); -} // namespace LHCb::Event::v2 diff --git a/Event/TrackEvent/Event/Track_SOA.h b/Event/TrackEvent/Event/Track_SOA.h index 996bd261107..137caad8c0a 100644 --- a/Event/TrackEvent/Event/Track_SOA.h +++ b/Event/TrackEvent/Event/Track_SOA.h @@ -19,7 +19,6 @@ #include "Kernel/meta_enum.h" #include "LHCbMath/SIMDWrapper.h" #include "LHCbMath/Vec3.h" -#include "SOAExtensions/ZipUtils.h" /** * Track data after the Kalman fit diff --git a/Kernel/SOAContainer/CMakeLists.txt b/Kernel/SOAContainer/CMakeLists.txt deleted file mode 100644 index 29006a65724..00000000000 --- a/Kernel/SOAContainer/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################### -# (c) Copyright 2018 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -################################################################################ -# Package: SOAContainer -################################################################################ -gaudi_subdir(SOAContainer) -set_property(DIRECTORY PROPERTY INSTALLS_LOCAL_HEADERS TRUE) - -# This uses the upstream SOAContainer repository as submodule. - -# In the submodules directory, the .gaudi_project_ignore files disables -# automatic discovery of CMakeLists.txt files, which is why the -# submodules/SOAContainer/CMakeLists.txt file needs to be added explicitly here. -# We do not want to automatically discover any of the other CMakeLists.txt -# files in the subdirectories therein (therefore disabling in the first place). - -if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/submodules/SOAContainer/CMakeLists.txt") - set(SOAContainer_disable_tests ON) - set(SOAContainer_header_destination ${CMAKE_INSTALL_PREFIX}/include/SOAContainer) - add_subdirectory(submodules/SOAContainer) -else() - message(FATAL_ERROR -"SOAContainer submodule file not found -from the directory: ${CMAKE_SOURCE_DIR} -you possibly need to run: `git submodule update --init --recursive` - -see also https://twiki.cern.ch/twiki/bin/view/LHCb/Git4LHCb#Dealing_with_submodules_when_cha") -endif() diff --git a/Kernel/SOAContainer/SOAContainer b/Kernel/SOAContainer/SOAContainer deleted file mode 120000 index 95e6057b64f..00000000000 --- a/Kernel/SOAContainer/SOAContainer +++ /dev/null @@ -1 +0,0 @@ -submodules/SOAContainer/include \ No newline at end of file diff --git a/Kernel/SOAContainer/submodules/.gaudi_project_ignore b/Kernel/SOAContainer/submodules/.gaudi_project_ignore deleted file mode 100644 index 6c1d7ecf44a..00000000000 --- a/Kernel/SOAContainer/submodules/.gaudi_project_ignore +++ /dev/null @@ -1 +0,0 @@ -# ignore all submodules by default diff --git a/Kernel/SOAExtensions/CMakeLists.txt b/Kernel/SOAExtensions/CMakeLists.txt deleted file mode 100644 index 6deeba96de6..00000000000 --- a/Kernel/SOAExtensions/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -############################################################################### -# (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -################################################################################ -# Package: SOAExtensions -################################################################################ -gaudi_subdir(SOAExtensions) - -gaudi_depends_on_subdirs( - Kernel/SOAContainer - Kernel/LHCbKernel - Kernel/LHCbMath - GaudiAlg) - -gaudi_install_headers(SOAExtensions) -# as transitive dependency, projects that include SOAExtensions must also include Kernel/SOAContainer - -find_package(Boost) -find_package(Rangev3 REQUIRED) -find_package(cppgsl) -include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${RANGEV3_INCLUDE_DIR}) - -gaudi_add_unit_test(TestZipSelection - tests/src/TestSelection.cpp - INCLUDE_DIRS Kernel/SOAContainer cppgsl - LINK_LIBRARIES GaudiKernel - TYPE Boost) - -gaudi_add_unit_test(TestHanaAccessor - tests/src/hana_soa_access.cpp - INCLUDE_DIRS Kernel/LHCbMath - Link_LIBRARIES LHCbMathLib - TYPE Boost) - -gaudi_add_module( SOAExtensionExamples examples/src/*.cpp - INCLUDE_DIRS GaudiAlg Kernel/SOAContainer Kernel/SOAExtensions cppgsl - LINK_LIBRARIES GaudiAlgLib - ) - -gaudi_add_module( ZipBarrier src/*.cpp - INCLUDE_DIRS Kernel/SOAContainer Kernel/SOAExtensions GaudiAlg - LINK_LIBRARIES GaudiAlgLib - ) - - - -gaudi_add_test(QMTest QMTEST - ENVIRONMENT - BINARY_TAG=${BINARY_TAG} - STDOPTS=${CMAKE_CURRENT_SOURCE_DIR}/options - JOBOPTSEARCHPATH+=${CMAKE_CURRENT_SOURCE_DIR}/options - PYTHONPATH+=${CMAKE_CURRENT_SOURCE_DIR}/tests/qmtest - ) - diff --git a/Kernel/SOAExtensions/SOAExtensions/IncompatibleZipException.h b/Kernel/SOAExtensions/SOAExtensions/IncompatibleZipException.h deleted file mode 100644 index 3dbb4794469..00000000000 --- a/Kernel/SOAExtensions/SOAExtensions/IncompatibleZipException.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -#ifndef IncompatibleZipException_H -#define IncompatibleZipException_H 1 -#include <exception> // IWYU pragma: keep -// IWYU pragma: no_include <bits/exception.h> -#include <string> - -namespace Zipping { - /** @class IncompatibleZipException - * - * @brief Exception that's thrown when zipping Zipping::ZipContainers that are semantically incompatible - */ - class IncompatibleZipException final : public std::exception { - std::string m_message{"unspecified failure"}; ///< message in the exception with more details - - public: - /// default constructor deleted, intention is to always provide details - IncompatibleZipException() = default; - /// constructor with additional method - IncompatibleZipException( std::string s ) : m_message( std::move( s ) ) {} - /// print the contained message with details - std::string message() { return m_message; } - }; -} // namespace Zipping - -#endif diff --git a/Kernel/SOAExtensions/SOAExtensions/ZipAlgorithms.h b/Kernel/SOAExtensions/SOAExtensions/ZipAlgorithms.h deleted file mode 100644 index 44658d8f5dc..00000000000 --- a/Kernel/SOAExtensions/SOAExtensions/ZipAlgorithms.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -#ifndef ZipAlgorithms_h -#define ZipAlgorithms_h -#include "Kernel/AllocatorUtils.h" -#include "SOAContainer/SOAContainer.h" -#include "SOAExtensions/ZipContainer.h" -#include "SOAExtensions/ZipSelection.h" -#include <algorithm> - -namespace Zipping { - - /** - * @brief Create a new container that can be zipped to an input container with a per-element operation - * - * This overload version takes an owning SOA::Container, not a view. - * The operation is performed on every element of the input container and the return of the operation - * is added to the output container with emplace_back. - * The operation will usually be a lambda, but can be any valid input for std::invoke. - * The operation is applied to all inputs. - * - * @code - * Zipping::ZipContainer<SOA::Container<std::vector, TrackSkin>> tracks = ... - * auto muonids = Zipping::transform<MuonPIDSkin>( tracks, [](auto track) { MuonPID pid = ... ; return pid; } ); - * @endcode - * - * @tparam OUTSKIN SOA-skin for the output container - * @tparam CONTAINER underlying storage template (auto deduced, typically std::vector) - * @tparam INSKIN SOA-skin of the input container (auto deduced) - * @tparam Operation type of the operation (auto deduced) - * @param input input container - * @param operation the per-element operation for the transformation - * - * @return a Zipping::ZipContainer that can be zipped to the input container - */ - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, - template <typename> typename INSKIN, typename Operation> - auto transform( const Zipping::ZipContainer<SOA::Container<CONTAINER, INSKIN>>& input, Operation&& operation ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.zipIdentifier() ); - retval.reserve( input.size() ); - for ( auto in : input ) { retval.emplace_back( std::invoke( operation, in ) ); } - assert( retval.size() == input.size() ); - assert( Zipping::areSemanticallyCompatible( retval, input ) ); - return retval; - } - - /** - * @brief Create a new container that can be zipped to an input container with a per-element operation - * - * This overload version takes a non-owning SOA::View. - * The operation is performed on every element of the input container and the return of the operation - * is added to the output container with emplace_back. - * The operation will usually be a lambda, but can be any valid input for std::invoke. - * The operation is applied to all inputs. - * - * @code - * Zipping::ZipContainer<SOA::Container<std::vector, TrackSkin>> tracks = ... - * Zipping::ZipContainer<SOA::Container<std::vector, MuonPIDSkin>> muonids = ... - * auto proto_particles = Zipping::semantic_zip<ProtoParticleSkin>( tracks, muonids ); - * - * auto muon_isolations = Zipping::transform<MuonIsolationSkin, std::vector>( proto_particles, [](auto protop) { - * MuonIsolation iso = ... ; return iso; } ); - * @endcode - * - * @tparam OUTSKIN SOA-skin for the output container - * @tparam CONTAINER underlying storage template (not deduced, when in doubt probably std::vector) - * @tparam INVIEW type of the input ZipContainer<SOA::View ... - * @tparam Operation type of the operation (auto deduced) - * @param input input container - * @param operation the per-element operation for the transformation - * - * @return a Zipping::ZipContainer that can be zipped to the input container - */ - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, typename INVIEW, - typename Operation, typename = std::enable_if_t<!SOA::Utils::is_container<INVIEW>::value>> - auto transform( const Zipping::ZipContainer<INVIEW>& input, Operation&& operation ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.zipIdentifier() ); - retval.reserve( input.size() ); - for ( auto in : input ) { retval.emplace_back( std::invoke( operation, in ) ); } - assert( retval.size() == input.size() ); - assert( Zipping::areSemanticallyCompatible( retval, input ) ); - return retval; - } - - /** @brief Create a new container that can be zipped to an input container with a per-element operation - * - * The operation is performed on every element of the input container and the return of the operation - * is added to the output container with emplace_back. - * The operation will usually be a lambda, but can be any valid input for std::invoke. - * The operation is applied to all inputs. - * Only scalar operations are supported at the moment. - * - * @code - * LHCb::Pr::Forward::Tracks tracks{...}; - * auto ismuon = [](auto proxy_track){ return muonid; }; - * auto muonids = LHCb::Pr::transform<LHCb::Pr::Muon::PIDs>( tracks, ismuon ); - * @endcode - * - * @tparam Output output container - * @tparam Input underlying storage template (auto deduced) - * @tparam Operation type of the operation (auto deduced) - * @param input input container - * @param operation the per-element operation for the transformation - * - * @return a container that can be zipped to the input container - */ - template <typename Output, typename Input, typename Operation> - Output transform( Input const& input, Operation&& operation ) { - auto output = LHCb::make_obj_propagating_allocator<Output>( input, input.zipIdentifier() ); - output.reserve( input.size() ); - - for ( auto const in : input ) { output.emplace_back( std::invoke( operation, in ) ); } - - // Check consistency - if ( !Zipping::areSemanticallyCompatible( input, output ) ) { - throw GaudiException{"Asked to zip containers that are not semantically compatible", "LHCb::Pr::Zip", - StatusCode::FAILURE}; - } - if ( !Zipping::areSameSize( input, output ) ) { - throw GaudiException{"Asked to zip containers that are not the same size", "LHCb::Pr::Zip", StatusCode::FAILURE}; - } - return output; - } - - namespace details { - template <typename IndexSize, typename INPUT, typename OUTPUT, typename Operation, typename SELECTION> - auto transform( const INPUT& input, Operation&& operation, const SELECTION& sel, OUTPUT& retval ) { - retval.reserve( input.size() ); - assert( std::is_sorted( sel.begin(), sel.end() ) ); - - IndexSize i = 0; - auto selectionIterator = sel.begin(); - for ( ; i < input.size(); ++i ) { - if ( selectionIterator != sel.end() && *selectionIterator == i ) { - retval.emplace_back( std::invoke( operation, input[i] ) ); - ++selectionIterator; - } else { - retval.emplace_back(); // default / invalid construction - } - } - - assert( retval.size() == input.size() ); - assert( Zipping::areSemanticallyCompatible( retval, input ) ); - - return retval; - } - } // namespace details - - /** - * @brief Create a new container that can be zipped to an input container with a per-element operation - * - * This overload version takes an owning SOA::Container, not a view. - * The operation is applied to selected elements, for others the default constructed output object is created. - * The operation is performed on every element of the input container and the return of the operation - * is added to the output container with emplace_back. - * The operation will usually be a lambda, but can be any valid input for std::invoke. - * - * @code - * Zipping::ZipContainer<SOA::Container<std::vector, TrackSkin>> tracks = ... - * ExportedSelection<> large_ip_selection = ... - * auto muonids = Zipping::transform<MuonPIDSkin>( tracks, [](auto track) { MuonPID pid = ... ; return pid; }, - * large_ip_selection ); - * @endcode - * - * @tparam OUTSKIN SOA-skin for the output container - * @tparam CONTAINER underlying storage template (auto deduced, typically std::vector) - * @tparam INSKIN SOA-skin of the input container (auto deduced) - * @tparam Operation type of the operation (auto deduced) - * @tparam IndexSize Type for indices (auto deduced) - * @param input input container - * @param operation the per-element operation for the transformation - * @param sel selection of to-be-processed elements - * - * @return a Zipping::ZipContainer that can be zipped to the input container - */ - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, - template <typename> typename INSKIN, typename Operation, typename IndexSize> - auto transform( const Zipping::ZipContainer<SOA::Container<CONTAINER, INSKIN>>& input, Operation&& operation, - const ExportedSelection<IndexSize>& sel ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.zipIdentifier() ); - return details::transform<IndexSize>( input, operation, sel.m_indices, retval ); - } - - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, - template <typename> typename INSKIN, typename Operation, typename IndexSize> - auto - transform( const Zipping::SelectionView<Zipping::ZipContainer<SOA::Container<CONTAINER, INSKIN>>, IndexSize>& input, - Operation&& operation ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.m_container->zipIdentifier() ); - return details::transform<IndexSize>( *input.m_container, operation, *input.m_indices, retval ); - } - - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, - template <typename> typename INSKIN, typename Operation, typename IndexSize> - auto transform( - const Zipping::SelectionView<const Zipping::ZipContainer<SOA::Container<CONTAINER, INSKIN>>, IndexSize>& input, - Operation&& operation ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.m_container->zipIdentifier() ); - return details::transform<IndexSize>( *input.m_container, operation, *input.m_indices, retval ); - } - - /** - * @brief Create a new container that can be zipped to an input container with a per-element operation - * - * This overload version takes a non-owning SOA::View. - * The operation is applied to selected elements, for others the default constructed output object is created. - * The operation is performed on every element of the input container and the return of the operation - * is added to the output container with emplace_back. - * The operation will usually be a lambda, but can be any valid input for std::invoke. - * - * @code - * Zipping::ZipContainer<SOA::Container<std::vector, TrackSkin>> tracks = ... - * Zipping::ZipContainer<SOA::Container<std::vector, MuonPIDSkin>> muonids = ... - * auto proto_particles = Zipping::semantic_zip<ProtoParticleSkin>( tracks, muonids ); - * ExportedSelection<> large_ip_selection = ... - * - * auto muon_isolations = Zipping::transform<MuonIsolationSkin, std::vector>( proto_particles, [](auto protop) { - * MuonIsolation iso = ... ; return iso; }, large_ip_selection ); - * @endcode - * - * @tparam OUTSKIN SOA-skin for the output container - * @tparam CONTAINER underlying storage template (not deduced, when in doubt probably std::vector) - * @tparam INVIEW type of the input ZipContainer<SOA::View ... - * @tparam Operation type of the operation (auto deduced) - * @tparam IndexSize Type for indices (auto deduced) - * @param input input container - * @param operation the per-element operation for the transformation - * @param sel selection of to-be-processed elements - * - * @return a Zipping::ZipContainer that can be zipped to the input container - */ - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, typename INVIEW, - typename Operation, typename = std::enable_if_t<!SOA::Utils::is_container<INVIEW>::value>, - typename IndexSize> - auto transform( const Zipping::ZipContainer<INVIEW>& input, Operation&& operation, - const ExportedSelection<IndexSize>& sel ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.zipIdentifier() ); - return details::transform<IndexSize>( input, operation, sel.m_indices, retval ); - } - - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, typename INVIEW, - typename Operation, typename = std::enable_if_t<!SOA::Utils::is_container<INVIEW>::value>, - typename IndexSize> - auto transform( const Zipping::SelectionView<Zipping::ZipContainer<INVIEW>, IndexSize>& input, - Operation&& operation ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.m_container->zipIdentifier() ); - return details::transform<IndexSize>( input, operation, *input.m_indices, retval ); - } - - template <template <typename> typename OUTSKIN, template <typename...> class CONTAINER, typename INVIEW, - typename Operation, typename = std::enable_if_t<!SOA::Utils::is_container<INVIEW>::value>, - typename IndexSize> - auto transform( const Zipping::SelectionView<const Zipping::ZipContainer<INVIEW>, IndexSize>& input, - Operation&& operation ) { - Zipping::ZipContainer<SOA::Container<CONTAINER, OUTSKIN>> retval( input.m_container->zipIdentifier() ); - return details::transform<IndexSize>( input, operation, *input.m_indices, retval ); - } -} // namespace Zipping - -#endif // ZipAlgorithms_h diff --git a/Kernel/SOAExtensions/SOAExtensions/ZipContainer.h b/Kernel/SOAExtensions/SOAExtensions/ZipContainer.h deleted file mode 100644 index cd9bfb16705..00000000000 --- a/Kernel/SOAExtensions/SOAExtensions/ZipContainer.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -/** @file - * ZipContainer framework. Contains wrappers around SOA::Container and - * SOA::View types. This provides semantics for zipping that encodes if two - * containers are intended to be zipped together. E.g. RICH PID for downstream - * tracks shall not be zipped with forward tracks, even though this is valid - * from the point of view of C++ types and if accidentially there are as many - * forward tracks and downstream tracks in an event. - * - * The validation is done based on the ZipFamilyNumber type. Each ZipContainer - * has one ZipFamilyNumber as data member and ZipContainer with the same - * ZipFamilyNumber are meant to be zipped. This property is called - * 'semantically_compatible' in the following and can be checked with the - * function Zipping::areSemanticallyCompatible. Semantic compatibility is - * transitive (if A and B are compatible and A and C are compatible, then B and - * C are compatible, too). - * - * The term 'container family' refers to the set of all ZipContainers that are - * semantically compatible. Each ZipContainer belongs to exactly one container - * family. - * - * Semantic validation is only done in debug builds (more precisely based on - * ZIPPING_SEMANTIC_CHECKS) since it introduces a runtime overhead. Data - * members are not optimized out in the optimized build to provide ABI - * compatibility and ensure persistency formats do not depend on the - * architecture. - */ - -#ifndef ZipContainer_h -#define ZipContainer_h -#include "IncompatibleZipException.h" -#include "SOAContainer/SOASkin.h" -#include "SOAContainer/SOAUtils.h" -#include "SOAContainer/SOAView.h" -#include "ZipTraits.h" -#include "ZipUtils.h" -#include <tuple> // IWYU pragma: keep -#include <type_traits> -#include <utility> - -namespace Zipping { - /** @class ZipContainer ZipContainer.h - * - * @brief Container class for Zipping. - * - * ZipContainer wrap SOA::View types to add a ZipFamilyNumber data member. - * The templated base class SOA::View may be an owning SOA::Container or a - * non-owning SOA::View. - * - * @see Kernel/SOAExtensions/SOAExtensions/ZipContainer.h for the overall idea. - * - * @tparam CONTAINER wrapped SOA::View type - */ - template <typename CONTAINER> - class ZipContainer : public CONTAINER { - // types and usings - public: - using view_t = CONTAINER; - - // Zip functionality methods - public: - /// get number of container's container family - ZipFamilyNumber zipIdentifier() const { return m_zipIdentifier; } - - private: - ZipFamilyNumber m_zipIdentifier = generateZipIdentifier(); ///< container's family membership - - // constructors - public: - /** - * @brief General constructor when the container family already exists. - * - * ZipContainer can be constructed with a specific ZipFamilyNumber, all - * other constructor arguments are forwarded to the underlying - * SOAContainer-type. (Sorry for the cumbersome phrasing: - * `SOAContainer-type` is to make explicit that this may not be an - * SOA::Container, but also an SOA::View). - * - * @tparam ARGS SOA::View constructor argument types - * @param id container family number - * @param args SOA::View constructor arguments - */ - template <typename... ARGS> - ZipContainer( ZipFamilyNumber id, ARGS&&... args ) - : CONTAINER( std::forward<ARGS>( args )... ), m_zipIdentifier( id ) {} - - // If the first constructor argument is not a ZipFamilyNumber, generate a new ZipFamilyNumber and consider - // all constructor arguments as SOAContainer-type constructor arguments. - - // clang-format off - /** - * @brief General constructor when the container family does not yet exist. - * - * All constructor arguments are forwarded to the underlying SOAContainer-type. - * - * @tparam ARG First SOA::View constructor argument types (to validate that it's not a ZipFamilyNumber and not a copy constructor) - * @tparam ARGS Remaining SOA::View constructor argument types - * @param arg First SOA::View constructor argument - * @param args Remaining SOA::View constructor argument - */ - // clang-format on - template <typename ARG, typename... ARGS, - typename = std::enable_if_t<!std::is_same_v<ZipFamilyNumber, std::decay_t<ARG>> && - !std::is_same_v<ZipContainer, std::decay_t<ARG>>>> - ZipContainer( ARG&& arg, ARGS&&... args ) : CONTAINER( std::forward<ARG>( arg ), std::forward<ARGS>( args )... ) {} - - /// Default constructor generates a new ZipFamilyNumber and default constructs the underlying SOAContainer-type. - ZipContainer() = default; - - /// Copy constructor - ZipContainer( const ZipContainer& other ) = default; - - // FIXME: review! This does slicing. - /// Move constructor - ZipContainer( ZipContainer&& other ) = default; - - // convenience helpers - // - // FIXME: they remove CONTAINER::push_back from the overload set. This is - // not such a big issue for single column SOA::Container because there - // push_back isn't so great to begin with, and the enable_if should keep - // multi-field container push_backs intact. - // - // FIXME2: I'd prefer to enable/disable them here depending on the - // View/Container type of CONTAINER. In practice that's not a big issue - // because push_back would only get instantiated if called and then - // immediately fails in the function body. - public: - template <typename T> - auto push_back( T&& t ) - -> std::enable_if_t<view_t::self_type::fields_typelist::size() == 1 && - std::is_same_v<std::remove_reference_t<T>, - typename view_t::self_type::fields_typelist::template at<0>::type::type>> { - CONTAINER::emplace_back( std::forward<T>( t ) ); - } - template <typename T> - auto push_back( const T& t ) - -> std::enable_if_t<view_t::self_type::fields_typelist::size() == 1 && - std::is_same_v<std::remove_reference_t<T>, - typename view_t::self_type::fields_typelist::template at<0>::type::type>> { - CONTAINER::emplace_back( t ); - } - }; - - template <typename CONTAINER> - ZipContainer( ZipFamilyNumber, CONTAINER && )->ZipContainer<CONTAINER>; - - /** - * @brief zip multiple ZipContainer to one, with semantic checks in debug build. - * - * @see Kernel/SOAExtensions/SOAExtensions/ZipContainer.h for the overall idea. - * - * @tparam SKIN SOAContainer skin of the resulting zip (user provided) - * @tparam ZIPCONTAINER input ZipContainer types (deduced) - * @param views input ZipContainer - * - * @return the zipped view - SOAContainer's zip output with ZipFamilyNumber - */ - template <template <class> class SKIN, typename... ZIPCONTAINER, - typename = std::enable_if_t<SOA::Utils::ALL( SOA::impl::is_skin<SKIN>(), - has_semantic_zip_v<std::decay_t<ZIPCONTAINER>>... )>> - auto semantic_zip( ZIPCONTAINER&&... views ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( !areSemanticallyCompatible( views... ) ) { - throw IncompatibleZipException( "zipping from different container families" ); - } -#endif - - return ZipContainer{familyNumber( views... ), zip<SKIN>( std::forward<ZIPCONTAINER>( views )... )}; - } - - template <typename... ZIPCONTAINER, - typename = std::enable_if_t<SOA::Utils::ALL( has_semantic_zip_v<std::decay_t<ZIPCONTAINER>>... )>> - auto semantic_zip( ZIPCONTAINER&&... views ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( !areSemanticallyCompatible( views... ) ) { - throw IncompatibleZipException( "zipping from different container families" ); - } -#endif - - return ZipContainer{familyNumber( views... ), zip( std::forward<ZIPCONTAINER>( views )... )}; - } -} // namespace Zipping - -#endif diff --git a/Kernel/SOAExtensions/SOAExtensions/ZipSelection.h b/Kernel/SOAExtensions/SOAExtensions/ZipSelection.h deleted file mode 100644 index 2bf5e1991cf..00000000000 --- a/Kernel/SOAExtensions/SOAExtensions/ZipSelection.h +++ /dev/null @@ -1,543 +0,0 @@ -/* - * (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -// mostly copy and paste from Pr::Selection - -#ifndef ZIP_SELECTION -#define ZIP_SELECTION 1 -#include "ZipTraits.h" -#include "ZipUtils.h" -#include <algorithm> -#include <boost/type_index.hpp> -#include <cassert> -#include <cstddef> -#include <exception> // IWYU pragma: keep -#include <functional> -#include <iterator> -#include <limits> -#include <numeric> -#include <string> -#include <type_traits> -#include <utility> -#include <vector> -// IWYU pragma: no_include <bits/exception.h> -#include <cstdint> // IWYU pragma: keep -// IWYU pragma: no_include <bits/stdint-uintn.h> -#include "GaudiKernel/GaudiException.h" -#include "SOAExtensions/ZipContainer.h" // IWYU pragma: keep -#include <gsl/pointers> - -namespace Zipping { - - namespace details { - // Tag class to allow optimisation when we know the selection is a dummy. - struct alwaysTrue_t {}; - inline constexpr alwaysTrue_t alwaysTrue = alwaysTrue_t{}; - struct alwaysFalse_t {}; - inline constexpr alwaysFalse_t alwaysFalse = alwaysFalse_t{}; - - template <typename T> - inline auto const typename_v = boost::typeindex::type_id_with_cvr<T>().pretty_name(); - } // namespace details - - /** @class ExportedSelection ZipSelection.h - * - * @brief Exchange format for selections. - * - * Should normally be created with Zipping::makeSelection and used through - * Zipping::SelectionView. The ExportedSelection is intended to be written to - * TES and passed between algorithms. It facilitates creating a selection on - * one Zipping::ZipContainer and applied to another Zipping::ZipContainer. - * - * @tparam IndexSize The type used to represent indices into the underlying - * contiguous storage. Defaults to uint16_t, meaning by default you can only - * select 65536 objects... - */ - template <typename IndexSize = uint16_t> - struct ExportedSelection final { - // usings and types - using index_vector = typename std::vector<IndexSize>; ///< type of indices - - // data members - ZipFamilyNumber m_zipIdentifier; ///< Number of the container family this selection applies to - index_vector m_indices{}; ///< indices of selected elements - - // alwaysFalse is not default'ed here to make the default explicit at call side. - // no True option available in this option - /// Constructor from a container family number, defaults to zero selected elements - ExportedSelection( ZipFamilyNumber id, Zipping::details::alwaysFalse_t /*only for type, value unused*/ ) - : m_zipIdentifier( id ) {} - - /** - * @brief constructor from an existing container with no selection - * - * @tparam CONTAINER (deduced) type of Zipping::ZipContainer that is referenced - * @param container referenced container - * @param unused input (purely for type deduction and verbose call code) - */ - template <typename CONTAINER, typename = std::enable_if_t<has_semantic_zip_v<std::decay_t<CONTAINER>>>> - ExportedSelection( const CONTAINER& container, Zipping::details::alwaysFalse_t /*only for type, value unused*/ ) - : m_zipIdentifier{container.zipIdentifier()} {} - - /** - * @brief constructor from an existing container selecting everything - * - * @tparam CONTAINER (deduced) type of Zipping::ZipContainer that is referenced - * @param container referenced container - * @param unused input (purely for type deduction and verbose call code) - */ - template <typename CONTAINER, typename = std::enable_if_t<has_semantic_zip_v<std::decay_t<CONTAINER>>>> - ExportedSelection( const CONTAINER& container, Zipping::details::alwaysTrue_t /*only for type, value unused*/ ) - : m_zipIdentifier{container.zipIdentifier()}, m_indices( container.size(), IndexSize{} ) { - std::iota( m_indices.begin(), m_indices.end(), 0 ); - } - - // copy/move constructors, kept here to let the compiler complain should they ever get disabled accidentially - ExportedSelection( const ExportedSelection& other ) = default; - ExportedSelection( ExportedSelection&& other ) noexcept( std::is_nothrow_move_constructible<index_vector>::value ) = - default; - ~ExportedSelection() = default; - ExportedSelection& operator=( const ExportedSelection& ) = default; - ExportedSelection& - operator=( ExportedSelection&& ) noexcept( std::is_nothrow_move_constructible<index_vector>::value ) = default; - - /// comparison of ExportedSelection (same family and same selected indices) - friend bool operator==( ExportedSelection const& lhs, ExportedSelection const& rhs ) { - return lhs.m_zipIdentifier == rhs.m_zipIdentifier && lhs.m_indices == rhs.m_indices; - } - - // direct data construction - // NB: INDEX_VECTOR may be const - template <typename INDEX_VECTOR, - typename = std::enable_if_t<std::is_same_v<std::decay_t<INDEX_VECTOR>, index_vector>>> - ExportedSelection( INDEX_VECTOR&& indices, const ZipFamilyNumber id ) - : m_zipIdentifier( id ), m_indices( std::forward<INDEX_VECTOR>( indices ) ) {} - - /** - * @brief Semantic validation method - * - * Meant for library internal usage but provided publically anyway. - * - * @return Zipping::ZipFamilyNumber of the containers to which this application can be applied. - */ - ZipFamilyNumber zipIdentifier() const { return m_zipIdentifier; } - - /// number of selected elements - std::size_t size() const { return m_indices.size(); } - /// check if zero elements are selected - bool empty() const { return m_indices.empty(); } - - /** - * @brief Provide a selection of all elements that are contained in both input selections - * - * (Set theoretical) intersection of the input selections. Performs semantic validation in debug build. - * - * @param s1 a Zipping::ExportedSelection - * @param s2 a Zipping::ExportedSelection - */ - friend ExportedSelection set_intersection( ExportedSelection const& s1, ExportedSelection const& s2 ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( s1.zipIdentifier() != s2.zipIdentifier() ) { - throw GaudiException( "Performing set intersection on different container families.", - details::typename_v<ExportedSelection<>>, StatusCode::FAILURE ); - } -#endif - ExportedSelection<> retval{s1.zipIdentifier(), Zipping::details::alwaysFalse}; - retval.m_indices.reserve( std::min( s1.size(), s2.size() ) ); - // Use std::set_intersection to combine s1.m_indices and s2.m_indices into a new index container - std::set_intersection( s1.m_indices.begin(), s1.m_indices.end(), s2.m_indices.begin(), s2.m_indices.end(), - std::back_inserter( retval.m_indices ) ); - return retval; - } - - /** - * @brief Provide a selection of all elements that are contained in at least one input selections - * - * (Set theoretical) union of the input selections. Performs semantic validation in debug build. - * - * @param s1 a Zipping::ExportedSelection - * @param s2 a Zipping::ExportedSelection - */ - friend ExportedSelection set_union( ExportedSelection const& s1, ExportedSelection const& s2 ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( s1.zipIdentifier() != s2.zipIdentifier() ) { - throw GaudiException( "Performing set union on different container families.", - details::typename_v<ExportedSelection<>>, StatusCode::FAILURE ); - } -#endif - if ( s1.empty() ) { return s2; } - if ( s2.empty() ) { return s1; } - - ExportedSelection<> retval{s1.zipIdentifier(), Zipping::details::alwaysFalse}; - std::size_t est_csize = std::max( s1.m_indices.back(), s2.m_indices.back() ) + 1; - retval.m_indices.reserve( std::min( est_csize, s1.size() + s2.size() ) ); - // Use std::set_union to combine s1.m_indices and s2.m_indices into a new index container - std::set_union( s1.m_indices.begin(), s1.m_indices.end(), s2.m_indices.begin(), s2.m_indices.end(), - std::back_inserter( retval.m_indices ) ); - return retval; - } - - /** - * @brief Provide a selection of all elements that are contained in s1 but not s2 - * - * (Set theoretical) difference of the input selections. Performs semantic validation in debug build. - * - * @param s1 a Zipping::ExportedSelection - * @param s2 a Zipping::ExportedSelection - */ - friend ExportedSelection set_difference( ExportedSelection const& s1, ExportedSelection const& s2 ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( s1.zipIdentifier() != s2.zipIdentifier() ) { - throw GaudiException( "Performing set difference on different container families.", - details::typename_v<ExportedSelection<>>, StatusCode::FAILURE ); - } -#endif - if ( s2.empty() ) { return s1; } - - ExportedSelection<> retval{s1.zipIdentifier(), Zipping::details::alwaysFalse}; - retval.m_indices.reserve( s1.size() ); - // Use std::set_difference to combine s1.m_indices and s2.m_indices into a new index container - std::set_difference( s1.m_indices.begin(), s1.m_indices.end(), s2.m_indices.begin(), s2.m_indices.end(), - std::back_inserter( retval.m_indices ) ); - return retval; - } - - /** - * @brief Provide a selection of all elements that are contained in exactly one of s1 and s2 - * - * (Set theoretical) symmetric difference of the input selections. Performs semantic validation in debug build. - * - * @param s1 a Zipping::ExportedSelection - * @param s2 a Zipping::ExportedSelection - */ - friend ExportedSelection set_symmetric_difference( ExportedSelection const& s1, ExportedSelection const& s2 ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( s1.zipIdentifier() != s2.zipIdentifier() ) { - throw GaudiException( "Performing set symmetric difference on different container families.", - details::typename_v<ExportedSelection<>>, StatusCode::FAILURE ); - } -#endif - if ( s1.empty() ) { return s2; } - if ( s2.empty() ) { return s1; } - - ExportedSelection<> retval{s1.zipIdentifier(), Zipping::details::alwaysFalse}; - std::size_t est_csize = std::max( s1.m_indices.back(), s2.m_indices.back() ) + 1; - retval.m_indices.reserve( std::min( est_csize, s1.size() + s2.size() ) ); - // Use std::set_symmetric_difference to combine s1.m_indices and s2.m_indices into a new index container - std::set_symmetric_difference( s1.m_indices.begin(), s1.m_indices.end(), s2.m_indices.begin(), s2.m_indices.end(), - std::back_inserter( retval.m_indices ) ); - return retval; - } - - friend bool includes( ExportedSelection const& s1, ExportedSelection const& s2 ) { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( s1.zipIdentifier() != s2.zipIdentifier() ) { - throw GaudiException( "Performing set includes on different container families.", - details::typename_v<ExportedSelection<>>, StatusCode::FAILURE ); - } -#endif - return std::includes( s1.m_indices.begin(), s1.m_indices.end(), s2.m_indices.begin(), s2.m_indices.end() ); - } - }; - - /** @class SelectionView - * - * Allows to access selected element of a ZipContainer ("storage container" - * in the following). Not intended as exchange format on TES, exchange via - * `export_selection` and constructor. The backend behaviour is a container - * of indices through which container access (selection[42], - * selection.begin(), selection.begin()+5) is redirected. - * - * Does not own either the "data" nor the "selection". - * - * Should get created from an ExportedSelection, by means of makeSelection - * below as initial creation. - * - * @tparam CONTAINER The "selected" container (most likely an SOA::View) - * @tparam IndexSize The type used to represent indices into the underlying - * contiguous storage. Defaults to uint16_t, meaning by default you can only - * select 65536 objects... - */ - - template <typename CONTAINER, typename IndexSize = uint16_t, - typename = std::enable_if_t<has_semantic_zip_v<std::decay_t<CONTAINER>>>> - struct SelectionView { - // TODO in optimised build we could reduce sizeof(SelectionView) by 40% by - // using a single pointer in container_t and - // using an index_vector type that imposes size()==capacity() - - // usings and types - using proxy_type = typename std::decay_t<CONTAINER>::proxy; // make it easier to write generic code - // that can handle both containers and - // SelectionViews - using container_t = std::decay_t<CONTAINER>; - using index_vector = typename std::vector<IndexSize>; - - // data members - gsl::not_null<const container_t*> m_container; ///< Container from which elements are selected - /// Container of selected indices (member of a Zipping::ExportedSelection) - gsl::not_null<const index_vector*> m_indices; - - // Custom iterator class for looping through the index vector but - // dereferencing to values in the actual container - struct const_iterator { - using index_iter_type = typename index_vector::const_iterator; - using value_type = typename CONTAINER::proxy; - using difference_type = typename index_iter_type::difference_type; - using iterator_category = std::random_access_iterator_tag; - // provide these to enable STL algorithms - using pointer = const value_type*; // for iterator_traits - using reference = const value_type&; // for iterator_traits - - gsl::not_null<const container_t*> m_container; - index_iter_type m_iter; - - value_type const operator*() const { return ( *m_container )[*m_iter]; } - - friend bool operator==( const_iterator const& lhs, const_iterator const& rhs ) { - return lhs.m_container == rhs.m_container && lhs.m_iter == rhs.m_iter; - } - - friend bool operator!=( const_iterator const& lhs, const_iterator const& rhs ) { return !( lhs == rhs ); } - - friend difference_type operator-( const_iterator const& lhs, const_iterator const& rhs ) { - return lhs.m_iter - rhs.m_iter; - } - - const_iterator operator+( difference_type n ) const { return {m_container, m_iter + n}; } - - const_iterator& operator-=( difference_type n ) const { - m_iter -= n; - return *this; - } - - const_iterator& operator+=( difference_type n ) const { - m_iter += n; - return *this; - } - - const_iterator operator-( difference_type n ) const { return {m_container, m_iter - n}; } - - const_iterator& operator++() { - ++m_iter; - return *this; - } - - const_iterator& operator--() { - --m_iter; - return *this; - } - }; - - /** - * @brief Create an ExportedSelection for further exchange - * - * This creates a copy of the ExportedSelection from which the SelectionView got created. - * - * @return An ExportedSelection (no internal references/pointers to objects that might go out of context) - */ - ExportedSelection<IndexSize> export_selection() { - return ExportedSelection<IndexSize>( *m_indices, m_container->zipIdentifier() ); - } - - /** - * @brief Turn ExportedSelection into SelectionView that grants access to container elements. - * - * @param container ZipContainer with the actual data - * @param selection ExportedSelection with the elements that are to be accessed - */ - SelectionView( const container_t* container, const ExportedSelection<IndexSize>& selection ) - : m_container{container}, m_indices{&selection.m_indices} { -#ifdef ZIPPING_SEMANTIC_CHECKS - if ( selection.zipIdentifier() != container->zipIdentifier() ) { - throw GaudiException( "Building SelectionView from an ExportedSelection of a different container family.", - details::typename_v<SelectionView>, StatusCode::FAILURE ); - } -#endif - } - - /** - * @brief iterator to the first selected element - * - * const in any case since SelectionView only provide a look, no touch, at the data - */ - const_iterator begin() const { return {m_container, m_indices->begin()}; } - /** - * @brief const iterator to the first selected element (same as begin(), but provided for stl container conformity) - */ - const_iterator cbegin() const { return begin(); } - - /** - * @brief iterator to the after-last selected element - * - * const in any case since SelectionView only provide a look, no touch, at the data - */ - const_iterator end() const { return {m_container, m_indices->end()}; } - /** - * @brief const iterator to the after-last selected element (same as end(), provided for stl container conformity) - */ - const_iterator cend() const { return end(); } - - /** - * @brief last selected element - */ - proxy_type const back() const { return ( *m_container )[m_indices->back()]; } - /** - * @brief first selected element - */ - proxy_type const front() const { return ( *m_container )[m_indices->front()]; } - - /** - * @brief number of selected elements - */ - std::size_t size() const { return m_indices->size(); } - - /** - * @brief if the selection is empty (true: zero selected elements; false: more than zero elements) - */ - bool empty() const { return m_indices->empty(); } - - /** - * @brief the n-th selected element - */ - proxy_type const operator[]( std::size_t n ) const { - assert( n < size() ); - return ( *m_container )[( *m_indices )[n]]; - } - - /** - * @brief Compares two selection views (requires the *same* backing container) - * - * The comparison falls back to equality of the selected indices and falls back to the == operator of the underlying - * Zipping::ZipContainer<SOA::View ... - * - * @return true if the SelectionViews are equal - */ - friend bool operator==( SelectionView const& lhs, SelectionView const& rhs ) { - return lhs.m_container == rhs.m_container && ( *lhs.m_indices ) == ( *rhs.m_indices ); - } - - /** - * @brief Compares two selection views (requires the *same* backing container) - * - * The comparison falls back to equality of the selected indices and falls back to the == operator of the underlying - * SOA::View. - * - * @return true if the SelectionViews are unequal - */ - friend bool operator!=( SelectionView const& lhs, SelectionView const& rhs ) { return !( lhs == rhs ); } - - /** - * Refine a selection. - * - * @param predicate: the selection criterion, typically a lambda or function pointer. - * FIXME: at the moment this does not invoke - * std::invoke, thus not allowing SOA-Proxy methods due - * to corner cases in proxy forwarding that turned out - * problematic with templated proxy constructors that - * forward to underlying data constructors. - * @param reserveCapacity: anticipated number of selected objects. If no - * "correct" guess is available, prefer to guess too - * high rather than too low. - * @returns A new Exported selection. I.e. the existing SelectionView is not modified. - */ - template <typename Predicate> - [[nodiscard]] ExportedSelection<IndexSize> select( Predicate&& predicate, int reserveCapacity = -1 ) const { - ExportedSelection<IndexSize> retval( m_container->zipIdentifier(), details::alwaysFalse ); - retval.m_indices.reserve( reserveCapacity < 0 ? m_indices->size() : reserveCapacity ); - std::copy_if( m_indices->begin(), m_indices->end(), std::back_inserter( retval.m_indices ), - [&]( auto i ) { return predicate( ( *m_container )[i] ); } ); - return retval; - } - }; - - /** - * @brief standard method to create a selection - * - * This creates an `ExportedSelection`. To immediately use the selection (as - * `SelectionView`), create a SelectionView manually. - * - * @tparam CONTAINER type of `Zipping::ZipContainer`from which objects will be selected (automatically detected) - * @tparam Predicate callable type to specify the selection (automatically detected) - * @tparam IndexSize variable type for indexing (default uint16_t is good enough for 65536 input objects) - * @param container container from which objects are selected - * @param predicate selection criterion, typically a lambda `[](auto obj) -> bool { ... return ...;}` - * - * @return ExportedSelection to select objects for which the predicate returns true. - */ - template <typename CONTAINER, typename Predicate = details::alwaysTrue_t, typename IndexSize = uint16_t> - ExportedSelection<IndexSize> makeSelection( const CONTAINER* container, Predicate&& predicate = {}, - int reserveCapacity = -1 ) { - using container_t = std::decay_t<CONTAINER>; - if ( container->size() >= typename container_t::size_type( std::numeric_limits<IndexSize>::max() ) ) { - throw GaudiException{"Index overflow: " + std::to_string( container->size() - 1 ) + " > " + - std::to_string( std::numeric_limits<IndexSize>::max() ) + - details::typename_v<SelectionView<container_t>>, - details::typename_v<SelectionView<container_t>>, StatusCode::FAILURE}; - } - ExportedSelection<IndexSize> retval( container->zipIdentifier(), details::alwaysFalse ); - - if constexpr ( std::is_same_v<std::decay_t<Predicate>, details::alwaysTrue_t> ) { - retval.m_indices.resize( container->size() ); - std::iota( retval.m_indices.begin(), retval.m_indices.end(), 0 ); - } else if constexpr ( std::is_same_v<std::decay_t<Predicate>, details::alwaysFalse_t> ) { - if ( reserveCapacity >= 0 ) { retval.m_indices.reserve( reserveCapacity ); } - } else { - retval.m_indices.reserve( reserveCapacity < 0 ? container->size() : reserveCapacity ); - auto offset = 0; - for ( auto const i : *container ) { - if ( std::invoke( predicate, i ) ) { retval.m_indices.push_back( offset ); } - ++offset; - } - } - return retval; - } - - // Template parameter deduction guides - template <typename T, typename... Args> - SelectionView( T*, Args... )->SelectionView<T>; - - namespace details { - // Helpers for requireSelection<S> below - template <typename T> - struct isSelectionHelper : std::false_type {}; - - template <typename C, typename I> - struct isSelectionHelper<SelectionView<C, I>> : std::true_type {}; - - template <typename S> - inline constexpr bool isSelection_v = details::isSelectionHelper<S>::value; - } // namespace details - - // Helper to determine whether a type is a SelectionView - template <typename S> - using requireSelection = std::enable_if_t<details::isSelection_v<S>>; - - // Value-by-value comparison, don't care whether lhs and rhs are actually - // views onto the same container. - template <typename S, typename = requireSelection<S>> - bool equal_values( S const& lhs, S const& rhs ) { - return std::equal( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); - } - - template <typename S, typename = requireSelection<S>> - bool equal_values( S const& lhs, typename S::container_t const& rhs ) { - return std::equal( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); - } - - template <typename S, typename = requireSelection<S>> - bool equal_values( typename S::container_t const& lhs, S const& rhs ) { - return equal_values( rhs, lhs ); - } -} // namespace Zipping - -#endif diff --git a/Kernel/SOAExtensions/SOAExtensions/ZipTraits.h b/Kernel/SOAExtensions/SOAExtensions/ZipTraits.h deleted file mode 100644 index b0054ad33a7..00000000000 --- a/Kernel/SOAExtensions/SOAExtensions/ZipTraits.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -#ifndef ZipTraits_h -#define ZipTraits_h 1 -#include "SOAContainer/SOAUtils.h" -#include <type_traits> - -namespace Zipping { - template <typename CONTAINER> - class ZipContainer; - - namespace details { - /** @class has_semantic_zip_helper ZipTraits.h - * - * @brief helper type for Zipping::has_semantic_zip. Not intended for use outside ZipTraits.h - * - * @tparam T any other type than a Zipping::ZipContainer - */ - template <typename T> - struct has_semantic_zip_helper : std::false_type {}; - - /** - * @brief template specialization of helper type for Zipping::has_semantic_zip. Not intended for use outside - * ZipTraits.h - * - * @tparam SOA::View that is wrapped in a Zipping::ZipContainer - */ - template <typename VIEW> - struct has_semantic_zip_helper<ZipContainer<VIEW>> - : std::bool_constant<SOA::Utils::is_view<std::decay_t<VIEW>>::value> {}; - } // namespace details - - /** @class has_semantic_zip ZipTraits.h - * - * @brief Type trait type to ZipContainers. Whether or not a type can be argument/return to 'semantic_zip'. - * - * @tparam type of which availability of 'Zipping::semantic_zip' is queried - */ - - // remove const and reference from ZipContainer before going one level deeper - template <typename T> - using has_semantic_zip = details::has_semantic_zip_helper<std::decay_t<T>>; - - /** - * @brief Type trait value to ZipContainers. Whether or not a type can be argument/return to 'semantic_zip'. - * - * @tparam type of which availability of 'Zipping::semantic_zip' is queried - */ - template <typename VIEW> - constexpr static bool has_semantic_zip_v = has_semantic_zip<VIEW>::value; -} // namespace Zipping - -#endif diff --git a/Kernel/SOAExtensions/examples/options/BarrierExamples.py b/Kernel/SOAExtensions/examples/options/BarrierExamples.py deleted file mode 100644 index 25102e4c75e..00000000000 --- a/Kernel/SOAExtensions/examples/options/BarrierExamples.py +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright (C) 2019 CERN for the benefit of the LHCb collaboration -# Author: Paul Seyfert <pseyfert@cern.ch> -# -# This software is distributed under the terms of the GNU General Public -# Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". -# -# In applying this licence, CERN does not waive the privileges and immunities -# granted to it by virtue of its status as an Intergovernmental Organization -# or submit itself to any jurisdiction. - -# A barrier consists of 4 steps: -# -# 1+2: A gatherer and a merger. The gatherer reading data from a list of -# location and stores un-merged in an intermediate location. The merger merges -# the data properly. With ZipSelections, the gatherer stores a vector of -# ExportedSelection*s* in the intermediate location, the merger stores *one* -# ExportedSelection. -# -# 3: A transformer, that does actual work. I.e. for all selected tracks, -# compute "the isolation", compute RichPID, ... , in general, perform any -# operation that is computationally so expensive that we do not want to perform -# it on all input objects, but that will also be a common task among multiple -# trigger/prucing lines. -# -# 4: A scatterer, that distributes the output from the *one* output of the -# transformer back to all lines, such that each line receives only the -# transformed output of what they requested (the RichPIDs for the tracks it -# selected, not of all other tracks some other line selected). In the case of -# the ExportedSelection, such a scatterer is not needed. -# -# See also: -# https://indico.cern.ch/event/797774/contributions/3316748/attachments/1803283/2941932/LHCC_19_final.pdf - -# * In this example, a bunch of integers is Produced by -# ZipBarrierExampleProducer. -# * A bunch of ZipBarrierExampleSelector*s* select the integers they are -# interested in (in this simple example, numbers that are divisible by some -# Divisor are selected). -# * The "expensive" task is squaring the numbers, as done by -# ZipBarrierExampleWorker -# * PrintInts, PrintSquaredInts, PrintIntsAndSquaredInts print the data of various -# selections. -# -# What a reader should ideally understand: -# * How to configure a ZipBarrierGatherer and ZipBarrierMerger -# * How to use the output of a transformer together with the pre-existing -# ExportedSelection to process only selected output from the transformer -# (i.e. use a single ExportedSelection throughout a sprucing/trigger line -# with changing data columns) - -from Configurables import Examples__ZipBarrierExampleSelector as ZipBarrierExampleSelector -from Configurables import Examples__PrintInts as PrintInts -from Configurables import Examples__PrintSquaredInts as PrintSquaredInts -from Configurables import Examples__PrintIntsAndSquaredInts as PrintIntsAndSquaredInts -from Configurables import Examples__ZipBarrierExampleProducer as ZipBarrierExampleProducer -from Configurables import Examples__ZipBarrierExampleWorker as ZipBarrierExampleWorker -from Configurables import ZipBarrierGatherer, ZipBarrierMerger -from Gaudi.Configuration import * - -# Application setup -app = ApplicationMgr() -# - Algorithms -prod = ZipBarrierExampleProducer() -prod.OutputLocation = "/Event/OriginalVector" -prod.OutputSelection = "/Event/AllSelection" - -sel1 = ZipBarrierExampleSelector("selectall") -sel1.Divisor = 1 -sel1.OutputSelection = "/Event/Select_1" - -sel2 = ZipBarrierExampleSelector("selecteven") -sel2.Divisor = 2 -sel2.OutputSelection = "/Event/Select_2" - -sel3 = ZipBarrierExampleSelector("select_every_third") -sel3.Divisor = 3 -sel3.OutputSelection = "/Event/Select_3" - -sel4 = ZipBarrierExampleSelector("select_every_fourth") -sel4.Divisor = 4 -sel4.OutputSelection = "/Event/Select_4" - -sels = [sel1, sel2, sel3, sel4] -for sel in sels: - sel.InputLocation = prod.OutputLocation - sel.InputSelection = prod.OutputSelection - -gather1 = ZipBarrierGatherer("gather_all") -gather1.InputSelections = [sel.OutputSelection.Path for sel in sels] -gather1.OutputSelection = "/Event/AllGathers" -merger1 = ZipBarrierMerger("merge_all") -merger1.InputSelection = gather1.OutputSelection -merger1.OutputSelection = "/Event/AllMerges" - -gather2 = ZipBarrierGatherer("gather_rares") -gather2.InputSelections = [sel.OutputSelection.Path for sel in [sel3, sel4]] -gather2.OutputSelection = "/Event/RareGathers" -merger2 = ZipBarrierMerger("merge_rares") -merger2.InputSelection = gather2.OutputSelection -merger2.OutputSelection = "/Event/RareMerges" -worker = ZipBarrierExampleWorker("worker_rares") -worker.InputSelection = merger2.OutputSelection -worker.InputLocation = prod.OutputLocation -worker.OutputLocation = "/Event/ProcessedVector" - -# Select_42 is never created. gather3 has it last, gather4 has it first in the inputs to test corner cases of the merging step. -gather3 = ZipBarrierGatherer("gather_rares_") -gather3.InputSelections = [sel.OutputSelection.Path - for sel in [sel3, sel4]] + ["/Event/Select_42"] -gather3.OutputSelection = "/Event/RareGathers_" -merger3 = ZipBarrierMerger("merge_rares_") -merger3.InputSelection = gather3.OutputSelection -merger3.OutputSelection = "/Event/RareMerges_" - -gather4 = ZipBarrierGatherer("gather_rares__") -gather4.InputSelections = ["/Event/Select_42"] + [ - sel.OutputSelection.Path for sel in [sel3, sel4] -] -gather4.OutputSelection = "/Event/RareGathers__" -merger4 = ZipBarrierMerger("merge_rares__") -merger4.InputSelection = gather4.OutputSelection -merger4.OutputSelection = "/Event/RareMerges__" - -gather5 = ZipBarrierGatherer("gather_rares___") -gather5.InputSelections = ["/Event/Select_42"] -gather5.OutputSelection = "/Event/RareGathers___" -merger5 = ZipBarrierMerger("merge_rares___") -merger5.InputSelection = gather5.OutputSelection -merger5.OutputSelection = "/Event/RareMerges___" - -topalgs = [ - prod, - sel1, - sel2, - sel3, - sel4, - gather1, - merger1, - gather2, - merger2, - gather3, - merger3, - gather4, - merger4, - # gather5, merger5, # throws -] - -somenumber = 1 -printers = [] -for a in topalgs: - if a in [prod, gather1, gather2, gather3, gather4, gather5]: continue - somenumber += 1 - printer = PrintInts("Printer_" + str(somenumber)) - printer.InputLocation = prod.OutputLocation.Path - printer.InputSelection = a.OutputSelection.Path - printers.append(printer) - -topalgs += [worker] -topalgs += printers - -printsquares = PrintSquaredInts("PrintRareSquares") -printsquares.InputLocation = worker.OutputLocation.Path -printsquares.InputSelection = worker.InputSelection.Path -printsquares_v = PrintIntsAndSquaredInts("PrintRareSquaresVerbose") -printsquares_v.InputSelection = worker.InputSelection.Path -printsquares_v.InputIntLocation = prod.OutputLocation.Path -printsquares_v.InputSquaredIntLocation = worker.OutputLocation.Path - -topalgs += [printsquares, printsquares_v] - -app.TopAlg = topalgs - -# - Events -app.EvtMax = 2 -app.EvtSel = "NONE" -app.HistogramPersistency = "NONE" diff --git a/Kernel/SOAExtensions/examples/options/apples_1.py b/Kernel/SOAExtensions/examples/options/apples_1.py deleted file mode 100644 index ee4189980f9..00000000000 --- a/Kernel/SOAExtensions/examples/options/apples_1.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2019 CERN for the benefit of the LHCb collaboration -# Author: Paul Seyfert <pseyfert@cern.ch> -# -# This software is distributed under the terms of the GNU General Public -# Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". -# -# In applying this licence, CERN does not waive the privileges and immunities -# granted to it by virtue of its status as an Intergovernmental Organization -# or submit itself to any jurisdiction. - -from Configurables import MessageSvc -from Gaudi.Configuration import * -from Configurables import Gaudi__Examples__IntDataProducer as IntDataProducer -from Configurables import LHCb__Examples__Harvester as Harvester -from Configurables import LHCb__Examples__Sorter as Sorter -from Configurables import LHCb__Examples__Rater as Rater -from Configurables import LHCb__Examples__Cook as Cook - -outputlevel = WARNING -# Application setup -app = ApplicationMgr() -# - Algorithms -app.TopAlg = [ - IntDataProducer(OutputLevel=outputlevel), - Harvester(OutputLevel=outputlevel), - Sorter(OutputLevel=outputlevel), - Rater(OutputLevel=outputlevel), - Cook(OutputLevel=outputlevel) -] - -# - Events -app.EvtMax = 2 -app.EvtSel = "NONE" -app.HistogramPersistency = "NONE" - -MessageSvc().Format = "% F%80W%S%7W%R%T %0W%M" diff --git a/Kernel/SOAExtensions/examples/src/Print.cpp b/Kernel/SOAExtensions/examples/src/Print.cpp deleted file mode 100644 index 47914a5ded0..00000000000 --- a/Kernel/SOAExtensions/examples/src/Print.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -/** @file - * - * Consumers that serve purely for the purpose of giving an example of a barrier - * using SOAExtensions. All algorithms in this file are consumers and print - * contents of TES locations while taking selections (in the form of ExportedSelection) - * into account. - * - */ - -#include "GaudiAlg/Consumer.h" -#include "barrier_types.h" - -namespace Examples { - using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t<::Algorithm>; - - /** @class PrintInts Print.cpp - * - * @brief Print the selected content of a NumberContainer - */ - struct PrintInts final - : Gaudi::Functional::Consumer<void( const NumberContainer&, const Zipping::ExportedSelection<>& ), BaseClass_t> { - PrintInts( const std::string& name, ISvcLocator* svcLoc ) - : Consumer( name, svcLoc, - { - KeyValue( "InputLocation", "/Event/MyInt" ), - KeyValue( "InputSelection", "/Event/SelectAll" ), - } ) {} - - void operator()( const NumberContainer& data, const Zipping::ExportedSelection<>& sel ) const override { - Zipping::SelectionView input{&data, sel}; - for ( const auto& i : input ) { info() << "found a " << i << endmsg; } - } - }; - - DECLARE_COMPONENT( PrintInts ) - - /** @class PrintSquaredInts Print.cpp - * - * @brief Print the selected content of a SquaredNumberContainer - */ - struct PrintSquaredInts final - : Gaudi::Functional::Consumer<void( const SquaredNumberContainer&, const Zipping::ExportedSelection<>& ), - BaseClass_t> { - PrintSquaredInts( const std::string& name, ISvcLocator* svcLoc ) - : Consumer( name, svcLoc, - { - KeyValue( "InputLocation", "/Event/MyInt" ), - KeyValue( "InputSelection", "/Event/SelectAll" ), - } ) {} - - void operator()( const SquaredNumberContainer& data, const Zipping::ExportedSelection<>& sel ) const override { - Zipping::SelectionView input{&data, sel}; - for ( const auto& i : input ) { info() << "found a " << i << endmsg; } - } - }; - - DECLARE_COMPONENT( PrintSquaredInts ) - - /** @class PrintIntsAndSquaredInts Print.cpp - * - * @brief Print the selected content of a (internally zipped) NumberContainer and a SquaredNumberContainer - */ - struct PrintIntsAndSquaredInts final - : Gaudi::Functional::Consumer<void( const NumberContainer&, const SquaredNumberContainer&, - const Zipping::ExportedSelection<>& ), - BaseClass_t> { - PrintIntsAndSquaredInts( const std::string& name, ISvcLocator* svcLoc ) - : Consumer( name, svcLoc, - { - KeyValue( "InputIntLocation", "/Event/MyInt" ), - KeyValue( "InputSquaredIntLocation", "/Event/MyInt" ), - KeyValue( "InputSelection", "/Event/SelectAll" ), - } ) {} - - void operator()( const NumberContainer& data1, const SquaredNumberContainer& data2, - const Zipping::ExportedSelection<>& sel ) const override { - auto data = Zipping::semantic_zip<NumberAndSquaredNumberSkin>( data1, data2 ); - Zipping::SelectionView input{&data, sel}; - for ( const auto& i : input ) { info() << "found a " << i << endmsg; } - } - }; - - DECLARE_COMPONENT( PrintIntsAndSquaredInts ) -} // namespace Examples diff --git a/Kernel/SOAExtensions/examples/src/Producer.cpp b/Kernel/SOAExtensions/examples/src/Producer.cpp deleted file mode 100644 index 200814f2cb4..00000000000 --- a/Kernel/SOAExtensions/examples/src/Producer.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -/** @file - * - * A producer that serve purely for the purpose of giving an example of a barrier - * using SOAExtensions. The algorithm produces a container of integers (in the - * ZipContainer format) and puts it onto TES, from where it is used as input - * into selections and transformers. - * - */ - -#include "GaudiAlg/Producer.h" -#include "barrier_types.h" - -namespace Examples { - using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t<::Algorithm>; - - /** @class ZipBarrierExampleProducer Producer.cpp - * - * @brief Create a NumberContainer - */ - struct ZipBarrierExampleProducer final - : Gaudi::Functional::Producer<std::tuple<NumberContainer, Zipping::ExportedSelection<>>(), BaseClass_t> { - - ZipBarrierExampleProducer( const std::string& name, ISvcLocator* svcLoc ) - : Producer( - name, svcLoc, - {KeyValue( "OutputLocation", "/Event/MyVector" ), KeyValue( "OutputSelection", "/Event/SelectAll" )} ) {} - - std::tuple<NumberContainer, Zipping::ExportedSelection<>> operator()() const override { - NumberContainer retval; - for ( int i = 1; i < 14; ++i ) retval.push_back( i ); - Zipping::ExportedSelection<> trivial_selection( retval, Zipping::details::alwaysTrue ); - return {std::move( retval ), std::move( trivial_selection )}; - } - }; - - DECLARE_COMPONENT( ZipBarrierExampleProducer ) -} // namespace Examples diff --git a/Kernel/SOAExtensions/examples/src/Select.cpp b/Kernel/SOAExtensions/examples/src/Select.cpp deleted file mode 100644 index dcc95b40e25..00000000000 --- a/Kernel/SOAExtensions/examples/src/Select.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -/** @file - * - * Selection algorithms (implemented as transformers in the GaudiFunctional framework) - * that serve purely for the purpose of giving an example of a barrier - * using SOAExtensions. A container of "data" is read from the TES and a selection - * (in the form of ExportedSelection) is written back to TES. - * - */ - -#include "GaudiAlg/Transformer.h" -#include "barrier_types.h" - -namespace Examples { - using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t<::Algorithm>; - - /** @class ZipBarrierExampleSelector Select.cpp - * - * @brief Select elements in a NumberContainer (if and only if they are divisible by "Divisor") - */ - struct ZipBarrierExampleSelector final - : Gaudi::Functional::Transformer< - Zipping::ExportedSelection<>( const NumberContainer&, const Zipping::ExportedSelection<>& ), BaseClass_t> { - ZipBarrierExampleSelector( const std::string& name, ISvcLocator* svcLoc ) - : Transformer( name, svcLoc, - { - KeyValue( "InputLocation", "/Event/MyInt" ), - KeyValue( "InputSelection", "/Event/SelectAll" ), - }, - KeyValue( "OutputSelection", "/Event/MySelection" ) ) {} - - Gaudi::Property<int> m_divisor{this, "Divisor", 2}; /// divisor that determines if a number is selected. - - Zipping::ExportedSelection<> operator()( const NumberContainer& data, - const Zipping::ExportedSelection<>& sel ) const override { - Zipping::SelectionView input{&data, sel}; - - return input.select( [this]( NumberContainer::proxy i ) { return ( i.number() % m_divisor ) == 0; } ); - } - }; - - DECLARE_COMPONENT( ZipBarrierExampleSelector ) -} // namespace Examples diff --git a/Kernel/SOAExtensions/examples/src/Transform.cpp b/Kernel/SOAExtensions/examples/src/Transform.cpp deleted file mode 100644 index 2eea653fc1e..00000000000 --- a/Kernel/SOAExtensions/examples/src/Transform.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2020 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -#include "GaudiAlg/Transformer.h" -#include "SOAExtensions/ZipAlgorithms.h" -#include "barrier_types.h" - -namespace Examples { - using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t<::Algorithm>; - - struct ZipBarrierExampleWorker final - : Gaudi::Functional::Transformer< - SquaredNumberContainer( const NumberContainer&, const Zipping::ExportedSelection<>& ), BaseClass_t> { - ZipBarrierExampleWorker( const std::string& name, ISvcLocator* svcLoc ) - : Transformer( name, svcLoc, - { - KeyValue( "InputLocation", "/Event/MyInt" ), - KeyValue( "InputSelection", "/Event/MySelection" ), - }, - KeyValue( "OutputLocation", "/Event/MyTransformedInts" ) ) {} - - SquaredNumberContainer operator()( const NumberContainer& data, - const Zipping::ExportedSelection<>& sel ) const override { - - // squaring a number is a (silly) example for a computationally expensive task that we want to perform only for - // selected inputs. The output type (SquaredNumber can be constructed from an int), but one still needs to - // retrieve the `number` data member from the `Number` proxy. - auto expensive_operation = []( auto input ) { return input.number() * input.number(); }; - return Zipping::transform<SquaredNumberSkin>( data, std::move( expensive_operation ), sel ); - } - }; - - DECLARE_COMPONENT( ZipBarrierExampleWorker ) -} // namespace Examples diff --git a/Kernel/SOAExtensions/examples/src/apples.cpp b/Kernel/SOAExtensions/examples/src/apples.cpp deleted file mode 100644 index 9980b302972..00000000000 --- a/Kernel/SOAExtensions/examples/src/apples.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -// functional algorithm things -#include "GaudiAlg/Producer.h" -#include "GaudiAlg/Transformer.h" -#include <tuple> - -// zipping -#include "SOAExtensions/ZipContainer.h" - -// selections -#include "SOAExtensions/ZipSelection.h" - -// local example classes -#include "classes.h" - -/** @file - * A minimal sequence of functional algorithms passing ZipContainers and ExportedSelections around - * - * The example is around harvesting of fruit. Apples are first harvested by a - * `Harvester`, this puts the start of a container family to the TES. - * - * The apples are then sorted by a `Sorter` (imagine a person sorting out which - * apples we want to process further). This produces a non-trivial - * 'ExportedSelection' object, which will then be used by algorithms later in - * the sequence to process or not process certain apples. - * - * Additional information for the apples are then computed by a `Rater`. - * Compared to the "old framework", the rater does neither alter the apples on - * TES, nor copy the apples and update some data members of them. The ratings - * of the apples are put on TES and can then be read by later algorithms in the - * sequence by means of a zip. - * - * A cook in the end is inspired by a vertexer: The cook produces fruit salads. - * Each salad consisting of several apples (in the current implementation - * exactly two, and each apple can be used in multiple salads). The Cook - * produces the start of a new container family. - */ - -namespace LHCb { - namespace Examples { - // Writing to and reading from TES shouldn't be done with zips, but rather broken down. - // (technical tl;dr: what gets written as zip cannot be read in parts; - // writing parts and zip simultaneously doesn't work because the zip is a - // view and return from operator() moves things in memory). - - // This is hard enough to read as it is, so after automatic formatting I adjust to "one return per line". - // clang-format off - using HarvesterOutput = - std::tuple<Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>, - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>, - Zipping::ExportedSelection<>>; - // clang-format on - - /** @class Harvester - * - * @brief an algorithm that writes "apples" to TES (seeded by an integer from GaudiExamples) - * - * @see Kernel/SOAExtensions/examples/src/apples.cpp for an overview of the example - */ - struct Harvester final : Gaudi::Functional::MultiTransformer<HarvesterOutput( const int& )> { - /// constructor (standard GaudiFunctional) - Harvester( const std::string& name, ISvcLocator* svcLoc ) - : MultiTransformer( name, svcLoc, {KeyValue{"Seed", "/Event/MyInt"}}, - {KeyValue{"Apple_Output", "/Event/Apples"}, - KeyValue{"Nutrient_Output", "/Event/Nutrients"}, - KeyValue{"Selection_Output", "/Event/HarvesterSelection"}} ) {} - - // counters mainly to see something in the logfiles - mutable Gaudi::Accumulators::AveragingCounter<int> m_harvested{ - this, "picked heavy apples"}; ///< a counter that counts produced apples - mutable Gaudi::Accumulators::AveragingCounter<float> m_weights{this, "apple weights"}; ///< a counter that - ///< averages apple weights - - /** - * @brief produce apples - * - * @param seed an integer (not really necessary for example, but assume most people want a transformer example) - * - * @return two zip'able containers (apples and their nutrients) and a selection that selects all apples - * - * @see Kernel/SOAExtensions/examples/src/classes.h for the example specific data types (apples and nutrients) - */ - HarvesterOutput operator()( const int& seed ) const override { - - // Technically we're not zipping anything within the Harvester, but to - // keep only one container API for producing and transforming, we're - // using them anyway. - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>> part1; - - // zip-compatibility with the previous container is "declared" through - // the constructor argument (the `part1.zipIdentifier()`). - // Leaving that part out and writing only `part2;` would work within the Harvester, but crash later. - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>> part2( - part1.zipIdentifier() ); // assign family number at construction! - - // now create some apples with rather meaningless numbers - for ( int i = 0; i < 42; ++i ) { - part1.push_back( ::Examples::Apple{0.2f + 0.001f * ( seed + i )} ); // an apple weighs 200g plus a bit more - part2.push_back( ::Examples::NutritionalContent{20.f, 500} ); - } - - bool do_monitoring = true; - if ( do_monitoring ) { - // Instead of using part1 and part2 separately, one can also zip them - // directly: Sadly push_back/emplace_back cannot be used on zips (so - // can't be used above for creating the apples. I'd prefer `auto - // apples = zip(part1,part2); apples.push_back(....); It would work - // if we didn't intend to write the components separately to TES - auto apples = Zipping::semantic_zip<::Examples::Harvester_OutputSkin>( part1, part2 ); - auto buf1 = m_harvested.buffer(); - auto buf2 = m_weights.buffer(); - - // Loop over apples and do something. - // Using STL algorithms is possible, too. - for ( auto apple : apples ) { - if ( apple.weight() > 0.210f ) buf1 += 1; - buf2 += apple.weight(); - } - } - - // There are multiple constructors for Selections. This one is the easiest select-everything. - // It doesn't matter if part1, part2, or apples is used here - only the size is relevant. - auto trivial_selection = Zipping::ExportedSelection{part1, Zipping::details::alwaysTrue}; - - // return the output to the main program - return {std::move( part1 ), std::move( part2 ), std::move( trivial_selection )}; - } - }; - DECLARE_COMPONENT( Harvester ) - - /** @class Sorter - * - * @brief Refine a selection of apples - * - * The main part of the signature of a selection refining algorithm is - * - * - In: some data containers and an Zipping::ExportedSelection - * - Out: an Zipping::ExportedSelection (refined version of the input ExportedSelection - * - * @see Kernel/SOAExtensions/examples/src/apples.cpp for an overview of the example - */ - struct Sorter final - : Gaudi::Functional::Transformer<Zipping::ExportedSelection<>( - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>&, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>&, - const Zipping::ExportedSelection<>& )> { - /// apple selection criterion - Gaudi::Property<float> m_minWeight{this, "minWeight", 0.225f, "minimum apple weight"}; - - /// constructor (standard GaudiFunctional) - Sorter( const std::string& name, ISvcLocator* svcLoc ) - : Transformer( name, svcLoc, - // clang-format off - {KeyValue{"Apple_Input", "/Event/Apples"}, - KeyValue{"Nutrient_Input", "/Event/Nutrients"}, - KeyValue{"Selection_Input", "/Event/HarvesterSelection"} - }, - KeyValue{"Selection_Output", "/Event/SorterSelection"} ) {} - // clang-format on - - /** - * @brief read in apples and nutritional contents and select which apples shall be processed further - * - * @param p1 first zip component - * @param p2 second zip component - * @param e preselection from the Harvester - * - * @return an ExportedSelection - */ - Zipping::ExportedSelection<> - operator()( const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>& p1, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>& p2, - const Zipping::ExportedSelection<>& e ) const override { - // p1, p2, e are variables only for the way from the framework to the creation of the SelectionView apple_input - // afterwards they're not used anymore. apple_input is the interesting input object. - // In other words the first two lines here are just boilerplate code - auto z = Zipping::semantic_zip<::Examples::Harvester_OutputSkin>( p1, p2 ); - Zipping::SelectionView apple_input( &z, e ); - - // selections can be refined with the `select` method that takes a - // "callable" (presumably most will resort to lambdas like here): - auto refined_exported_selection = - apple_input.select( [&]( auto apple ) { return apple.weight() > m_minWeight; } ); - // the callable should return a bool (or something that can be - // converted to bool) that is `true` if an object is selected, and - // `false` for rejection. - - // counters for the efficiency get updated - { - size_t i = 0; - auto buffer = m_npassed_cuts.buffer(); - for ( ; i < refined_exported_selection.size(); ++i ) buffer += true; // count the passes - for ( ; i < apple_input.size(); ++i ) buffer += false; // the rest is failed - } - - return refined_exported_selection; - } - - /// counter to monitor the Sorter's efficiency - mutable Gaudi::Accumulators::BinomialCounter<> m_npassed_cuts{this, "apple acceptance efficiency"}; - }; - DECLARE_COMPONENT( Sorter ) - - using RaterOutput = std::tuple<Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::MarketValueSkin>>, - Zipping::ExportedSelection<>>; - - /** @class Rater - * - * @brief Produce some additional data for an existing container family - * - * @see Kernel/SOAExtensions/examples/src/apples.cpp for an overview of the example - */ - struct Rater final - : Gaudi::Functional::MultiTransformer<RaterOutput( - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>&, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>&, - const Zipping::ExportedSelection<>& )> { - - /// constructor (standard GaudiFunctional) - Rater( const std::string& name, ISvcLocator* svcLoc ) - : MultiTransformer( - name, svcLoc, - // clang-format off - {KeyValue{"Apple_Input", "/Event/Apples"}, - KeyValue{"Nutrient_Input", "/Event/Nutrients"}, - KeyValue{"Selection_Input", "/Event/SorterSelection"}}, - {KeyValue{"Ratings", "/Event/RaterRatings"}, - KeyValue{"Selection_Output", "/Event/RaterSelection"}} ) {} - // clang-format on - - /** - * @brief reads two zip'able containers and a selection, outputs an additional zip container and a selection - * - * @param p1 first input zip component - * @param p2 second input zip component - * @param e selection of elements to be "upgraded" - * - * @return additional data container (ZipContainer) and selection (ExportedSelection) - */ - RaterOutput - operator()( const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>& p1, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>& p2, - const Zipping::ExportedSelection<>& e ) const override { - // as in the Sorter, these two lines are boilerplate code - auto all_input = Zipping::semantic_zip<::Examples::Harvester_OutputSkin>( p1, p2 ); - Zipping::SelectionView selected_input( &all_input, e ); - - ////// would violate constness of views - // Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::MarketValueSkin>> retval( - // all_input.zipIdentifier(), all_input.size(), - // ::Examples::MarketValue{} ); // the output shall be zip compatible. - // - // auto wide_zip = Zipping::semantic_zip<::Examples::FullAppleSkin>( all_input, retval ); - // Zipping::SelectionView selected_elements( &wide_zip, e ); - // - // for (auto apple: wide_zip) { - // if (selected_elements.end() != std::find(selected_elements.begin(), selected_elements.end(), apple) ) { - // apple.marketValue().how_good_it_looks_to_the_consumer = 10.; // every apple is a top quality - // apple! - // } else { - // apple.marketValue().how_good_it_looks_to_the_consumer = 0.; // padding - // } - // } - - // create a container with the ratings - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::MarketValueSkin>> retval( - all_input.zipIdentifier() ); - - // since the outputs have to be zipped to the original container, a - // push_back/emplace_back needs to be performed for *every* apple, not - // only selected ones. - for ( auto apple : all_input ) { - // check if the apple got selected for further processing - bool evaluate = ( selected_input.end() == std::find( selected_input.begin(), selected_input.end(), apple ) ); - - if ( evaluate ) { - // normally some expensive calculation would go here. - // In this example the Rater just makes all selected apples top apples. - retval.emplace_back( 10.f ); // top apple! - } else { - retval.emplace_back( 0.f ); // bad apple - } - } - - // No meaningful selection here, just preparing output - Zipping::ExportedSelection<> trivial_selection( all_input, Zipping::details::alwaysTrue ); - return {std::move( retval ), std::move( trivial_selection )}; - } - }; - DECLARE_COMPONENT( Rater ) - - using KitchenOutput = std::tuple<Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::FruitSaladSkin>>, - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::DishSkin>>, - Zipping::ExportedSelection<>>; - /** @class Cook - * - * The 'Cook' algorithm creates new zip'able containers that aren't zip compatible with the input. - * - * In turn a new feature here is that the created objects refer to input object: Each salad has indices of the - * apples it got created from. - * - * @brief Make fruit salads out of the apples - * - * @see Kernel/SOAExtensions/examples/src/apples.cpp for an overview of the example - */ - struct Cook final - : Gaudi::Functional::MultiTransformer<KitchenOutput( - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>&, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>&, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::MarketValueSkin>>&, - const Zipping::ExportedSelection<>& )> { - - /// constructor (standard GaudiFunctional) - Cook( const std::string& name, ISvcLocator* svcLoc ) - : MultiTransformer( name, svcLoc, - // clang-format off - {KeyValue{"Apple_Input", "/Event/Apples"}, - KeyValue{"Nutrient_Input", "/Event/Nutrients"}, - KeyValue{"Ratings", "/Event/RaterRatings"}, - KeyValue{"Selection_Input", "/Event/SorterSelection"}}, - {KeyValue{"Salad_Output", "/Event/CookSalad"}, - KeyValue{"Dish_Output", "/Event/CookDish"}, - KeyValue{"Selection_Output", "/Event/CookSelection"}} ) {} - // clang-format on - - /** - * @brief transform apples to fruit salad - * - * @param in1 zip'able input container about apples - * @param in2 zip'able input container about apples - * @param in3 zip'able input container about apples - * @param s selected apples - * - * @return zip'able containers for new container family "fruit salads" - */ - KitchenOutput operator()( - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::AppleSkin>>& in1, - [[maybe_unused]] const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::NutritionalContentSkin>>& - in2, - const Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::MarketValueSkin>>& in3, - const Zipping::ExportedSelection<>& s ) const override { - // boilerplate code for reading - auto tmp = Zipping::semantic_zip<::Examples::StoreSkin>( in1, in3 ); - auto input = Zipping::SelectionView( &tmp, s ); - - // creation of output containers (just like in Harvester) - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::FruitSaladSkin>> out1; - Zipping::ZipContainer<SOA::Container<std::vector, ::Examples::DishSkin>> out2( out1.zipIdentifier() ); - - // loop over all pairs of apples - for ( size_t apple_index_1 = 0; apple_index_1 < input.size(); apple_index_1++ ) { - for ( size_t apple_index_2 = apple_index_1 + 1; apple_index_2 < input.size(); apple_index_2++ ) { - // get the actual apples - auto apple1 = input[apple_index_1]; - auto apple2 = input[apple_index_2]; - - // apply some cut on the combination of apples: - // fruit salad must have a minimal weight - if ( apple1.weight() + apple2.weight() > 0.205f ) { - // If cuts are passed, create an output object by pushing into all output containers. - // The first component keeps the indices of the inputs - ::Examples::FruitSalad push_value1{std::vector<size_t>{apple_index_1, apple_index_2}}; - // Like before, mostly invented numbers. - ::Examples::Dish push_value2{apple1.apple().weight() + apple2.apple().weight(), - 500.f}; // the label in the store just lies about the calories - out1.push_back( push_value1 ); - out2.push_back( push_value2 ); - } - } - } - - // as before, a select-everyting selection goes along with every output - Zipping::ExportedSelection<> trivial_selection( out1, Zipping::details::alwaysTrue ); - return {std::move( out1 ), std::move( out2 ), std::move( trivial_selection )}; - } - }; - DECLARE_COMPONENT( Cook ) - } // namespace Examples -} // namespace LHCb diff --git a/Kernel/SOAExtensions/examples/src/barrier_types.h b/Kernel/SOAExtensions/examples/src/barrier_types.h deleted file mode 100644 index f9a253dda60..00000000000 --- a/Kernel/SOAExtensions/examples/src/barrier_types.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -/** @file - * - * Data types that are used in the example how to use SOAExtensions for a barrier. - * - */ - -#ifndef BARRIER_EXAMPLE_TYPES -#define BARRIER_EXAMPLE_TYPES - -#include "SOAContainer/SOAContainer.h" -#include "SOAContainer/SOAField.h" -#include "SOAContainer/SOASkin.h" -#include "SOAExtensions/ZipContainer.h" -#include "SOAExtensions/ZipSelection.h" -#include <vector> - -namespace Examples { - /* - * @class NumberField - * - * data type that is stored in a NumberContainer. - * - * @brief an alias for int for the type system (could be a track in a real LHCb example) - */ - SOAFIELD_TRIVIAL( NumberField, number, int ); - /* - * @class NumberSkin - * - * @brief data type that defines the proxy API of a NumberContainer. - */ - SOASKIN_TRIVIAL( NumberSkin, NumberField ); - /* - * @class SquaredNumberField - * - * data type that is stored in a SquaredNumberContainer. - * - * @brief an alias for int for the type system (could be a MUON PID in a real LHCb example) - */ - SOAFIELD_TRIVIAL( SquaredNumberField, squarednumber, int ); - /* - * @class SquaredNumberSkin - * - * @brief data type that defines the proxy API of a SquaredNumberContainer. - */ - SOASKIN_TRIVIAL( SquaredNumberSkin, SquaredNumberField ); - /* - * @class NumberAndSquaredNumberSkin - * - * @brief data type that defines the proxy API of a NumberAndSquaredNumberContainer. - */ - SOASKIN_TRIVIAL( NumberAndSquaredNumberSkin, NumberField, SquaredNumberField ); - - /* - * @class NumberContainer - * - * @brief container of NumberField objects in the SOAExtensions framework - */ - using NumberContainer = Zipping::ZipContainer<SOA::Container<std::vector, NumberSkin>>; - /* - * @class SquaredNumberContainer - * - * @brief container of SquaredNumberField objects in the SOAExtensions framework - */ - using SquaredNumberContainer = Zipping::ZipContainer<SOA::Container<std::vector, SquaredNumberSkin>>; - /* - * @class NumberAndSquaredNumberContainer - * - * @brief zip of a NumberContainer and a SquaredNumberContainer - */ - using NumberAndSquaredNumberContainer = Zipping::ZipContainer<SOA::Container<std::vector, SquaredNumberSkin>>; - -} // namespace Examples -#endif diff --git a/Kernel/SOAExtensions/examples/src/classes.cpp b/Kernel/SOAExtensions/examples/src/classes.cpp deleted file mode 100644 index 491a59a1c4b..00000000000 --- a/Kernel/SOAExtensions/examples/src/classes.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -#include "classes.h" -// purely to provide compilation of the header diff --git a/Kernel/SOAExtensions/examples/src/classes.h b/Kernel/SOAExtensions/examples/src/classes.h deleted file mode 100644 index 231509eb1ca..00000000000 --- a/Kernel/SOAExtensions/examples/src/classes.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -#include "SOAContainer/SOAContainer.h" -#include "SOAContainer/SOAField.h" -#include "SOAContainer/SOASkin.h" -#include "SOAExtensions/ZipContainer.h" -#include <vector> - -/** @file SOAExtensions/examples/src/classes.h - * - * @brief data types for the apple harvesting example - * - * General walkthrough for the example is in @see SOAExtensions/examples/src/apples.cpp - */ -namespace Examples { - - /** @class Apple classes.h - * - * @brief some, but not all information about an apple. - * - * Data types in an SOA container can be any C++ type. For lack of - * creativity/to keep the example simple, the class here contains just a - * float. For usage in `find` (to find a specifc apple in a selection / view) - * the apple has an unconventional comparison operator. This is to avoid the - * trouble of floating point comparisons within the example. - */ - struct Apple { - float m_weight; ///< weight of an apple in SI units, i.e. kg - - /// setter for apple weight - void setWeight( float w ) { m_weight = w; } - /// getter for apple weight - float weight() const { return m_weight; } - - /// apple equality operator (assume no two apples in nature are equal) - bool operator==( const Apple& other ) const { return &other == this; } - /// apple inequality operator (assume no two apples in nature are equal) - bool operator!=( const Apple& other ) const { return &other != this; } - }; - - /** @class NutritionalContent class.h - * - * @brief some other information about an apple (@see Apple class) - * - * For within the example, the 'NutritionalContent' information is produced - * by the same algorithm that produces the 'Apple'. - */ - struct NutritionalContent { - float m_calories; ///< caloric energy of an apple, in calories because nobody uses the SI unit in practice. - - /// getter for calories - float calories() const { return m_calories; } - /// setter for calories - void setCalories( float c ) { m_calories = c; } - - float m_vitaminC; ///< vitamin C content of the apple, in mol. - - /// equality operator (same as for Examples::Apple, not meant to be realistic c++ but convenience in example) - bool operator==( const NutritionalContent& other ) const { return &other == this; } - /// inequality operator (same as for Examples::Apple, not meant to be realistic c++ but convenience in example) - bool operator!=( const NutritionalContent& other ) const { return &other != this; } - }; - - /** @class MarketValue class.h - * - * @brief some more information about an apple (@see Apple class) - * - * In contrast to the 'NutritionalContent' information, the 'MarketValue' is - * produced by a different algorithm than the 'Apple'. (This is not visible - * from the struct definition, but only turns out this way in the data flow). - * This may be used in reality to compute genuine new information, but also - * to store computationally expensive data that could be derived from - * existing data. - */ - struct MarketValue { - /// how good it looks to the consumer on a scale from 0 to 10. - float m_looks; - /// getter for the apple's looks - float looks() { return m_looks; } - /// setter for the apple's looks - void setLooks( float l ) { m_looks = l; } - /// equality operator (same as for Examples::Apple, not meant to be realistic c++ but convenience in example) - bool operator==( const MarketValue& other ) const { return &other == this; } - /// inequality operator (same as for Examples::Apple, not meant to be realistic c++ but convenience in example) - bool operator!=( const MarketValue& other ) const { return &other != this; } - }; - - // SOA::Field s are the harder part to understand about the SOAContainer - // framework. - // - // If you're familiar with "tagged types", it's roughly that. If - // you're not familiar with tagged types, then I'm afraid the necessity for - // fields is not obvious from this example. Probably you can go ahead and - // ignore these three lines and remember that "fields go into a skin", and - // "types do not go into a skin". - // - // See also the documentation in SOAField.h - - /** - * @brief Makes the 'Apple' C++ type available to the SOA framework - * - * @param AppleField name of the hereby defined type AppleField - * @param apple name of the hereby defined accessor function apple() - * @param Apple regular C++ type that is made avalable to SOA - */ - SOAFIELD_TRIVIAL( AppleField, apple, Apple ); - - /** - * @brief Makes the 'NutritionalContent' C++ type available to the SOA framework - * - * @param NutritionalContentField name of the hereby defined type NutritionalContentField - * @param nutritionalContent name of the hereby defined accessor function nutritionalContent() - * @param NutritionalContent regular C++ type that is made avalable to SOA - */ - SOAFIELD_TRIVIAL( NutritionalContentField, nutritionalContent, NutritionalContent ); - - /** - * @brief Makes the 'MarketValueField' C++ type available to the SOA framework - * - * @param MarketValueField name of the hereby defined type MarketValueField - * @param marketValue name of the hereby defined accessor function marketValue() - * @param MarketValue regular C++ type that is made avalable to SOA - */ - SOAFIELD_TRIVIAL( MarketValueField, marketValue, MarketValue ); - - // SOA::Skins are the types exposed to the user of a zip. - // - // The user facing API of "objects" in SOA Containers are defined here. - // Trivial skins do not have any other API than accessors and constructors. - // These macros work as 'SOASKIN_TRIVIAL( <skin that gets defined> , <fields that get zipped> ... ); - // - // See also the documentation of SOASKIN_TRIVIAL in SOASkin.h - - /** - * @brief API of "objects" (technically 'proxies') in SOA Containers of 'Apples'. - * - * @param AppleSkin name of the hereby defined type - * @param AppleField field that is available in this skin - */ - SOASKIN_TRIVIAL( AppleSkin, AppleField ); - /** - * @brief API of "objects" (technically 'proxies') in SOA Containers of 'NutritionalContentSkin'. - * - * @param NutritionalContentSkin name of the hereby defined type - * @param NutritionalContentField field that is available in this skin - */ - SOASKIN_TRIVIAL( NutritionalContentSkin, NutritionalContentField ); - - /** - * @brief API for proxies in SOA Containers with 'AppleField' and 'MarketValueField' (zipped, or directly created) - * - * The skin here offers the possiblity to add methods to the proxy. The - * weight() method here allows the core developers to move the actual weight - * data from one field to another, store in a different unit, or generally - * change the representation of the information. - * - * In this simplified example however the method only shortens - * proxy.apple().weight() to proxy.apple() - * - * @param StoreSkin name of the hereby defined type - * @param AppleField field that is available in this skin - * @param MarketValueField field that is available in this skin - */ - SOASKIN( StoreSkin, AppleField, MarketValueField ) { - /** - * @brief Create all default methods (accessors and constructors) - */ - SOASKIN_INHERIT_DEFAULT_METHODS( StoreSkin ); - /** - * @return returns the weight from the zipped 'Apple' component - */ - float weight() { return this->apple().weight(); } - }; - - /** - * @brief API for proxies in SOA Containers with 'AppleField' and 'NutritionalContentField' - * - * The skin here offers the possiblity to add methods to the proxy. The - * weight() method here allows the core developers to move the actual weight - * data from one field to another, store in a different unit, or generally - * change the representation of the information. - * - * The calories_per_100g() method can be kept in place even if 'm_calories' - * or 'm_weight' are moved around between the zip components, or if the core - * developers choose to store directly the calories per 100g. Thus backend - * changes are decoupled from the API. - * - * @param Harvester_OutputSkin name of the hereby defined type - * @param AppleField field that is available in this skin - * @param NutritionalContentField field that is available in this skin - */ - SOASKIN( Harvester_OutputSkin, AppleField, NutritionalContentField ) { - /** - * @brief Create all default methods (accessors and constructors) - */ - SOASKIN_INHERIT_DEFAULT_METHODS( Harvester_OutputSkin ); - /** - * @return returns the weight from the zipped 'Apple' component - */ - float weight() { return this->apple().weight(); } - /** - * @return returns the calories per 100g weight to combine data from two fields. - */ - float calories_per_100g() { return 0.1f * this->nutritionalContent().calories() / this->apple().weight(); } - }; - - /** - * @brief API for proxies in SOA Containers with 'AppleField', 'NutritionalContentField', and 'MarketValueField' - * - * The skin here offers the possiblity to add methods to the proxy. The - * weight() method here allows the core developers to move the actual weight - * data from one field to another, store in a different unit, or generally - * change the representation of the information. - * - * The calories_per_100g() method can be kept in place even if 'm_calories' - * or 'm_weight' are moved around between the zip components, or if the core - * developers choose to store directly the calories per 100g. Thus backend - * changes are decoupled from the API. - * - * @param FullAppleSkin name of the hereby defined type - * @param AppleField field that is available in this skin - * @param NutritionalContentField field that is available in this skin - * @param MarketValueField field that is available in this skin - */ - SOASKIN( FullAppleSkin, AppleField, NutritionalContentField, MarketValueField ) { - /** - * @brief Create all default methods (accessors and constructors) - */ - SOASKIN_INHERIT_DEFAULT_METHODS( FullAppleSkin ); - /** - * @return returns the calories per 100g weight to combine data from two fields. - */ - float calories_per_100g() { return 0.1f * this->nutritionalContent().calories() / this->apple().weight(); } - }; - - /** - * @brief API for proxies in SOA Containers with 'NutritionalContentField', and 'MarketValueField' - * - * @param MarketValueSkin name of the hereby defined type - * @param MarketValueField field that is available in this skin - */ - SOASKIN( MarketValueSkin, MarketValueField ) { - /** - * @brief Create all default methods (accessors and constructors) - */ - SOASKIN_INHERIT_DEFAULT_METHODS( MarketValueSkin ); - /** - * @brief Custom constructor - * - * @param x the desired market value (capped between 0 and 10) - */ - MarketValueSkin( float x ) { - if ( x < 0.f ) - this->marketValue().setLooks( 0.f ); - else if ( x < 10.f ) - this->marketValue().setLooks( 10.f ); - else - this->marketValue().setLooks( x ); - } - }; - - /** @class FruitSalad classes.h - * - * @brief Yet another class for the example (multiple apples go into one fruit salad) - */ - struct FruitSalad { - std::vector<size_t> m_appleIndices; ///< references to individual objects are missing in SOAExtensions - /// getter of m_appleIndices - const std::vector<size_t>& appleIndices() const { return m_appleIndices; } - /// setter of m_appleIndices - void setAppleIndices( std::vector<size_t> ai ) { m_appleIndices = ai; } - }; - - /** @class Dish classes.h - * - * @brief A zip'able component for the FruitSalad (just to have something to zip) - */ - struct Dish { - float m_totalWeight; ///< the total weight of all apples in a fruit salad (so they don't have to be summed) - float m_totalCalories; ///< some information that is printed in the menu at the restaurant - }; - - /** @brief field definition for the FruitSalad - * - * Nothing meaningful to be documented here beyond copy and paste from other field in classes.h - */ - SOAFIELD_TRIVIAL( FruitSaladField, fruitSalad, FruitSalad ); - - /** @brief field definition for the Dish - * - * Nothing meaningful to be documented here beyond copy and paste from other field in classes.h - */ - SOAFIELD_TRIVIAL( DishField, dish, Dish ); - - /** @brief skin definition for the FruitSalad - * - * Nothing meaningful to be documented here beyond copy and paste from other skin in classes.h - */ - SOASKIN_TRIVIAL( FruitSaladSkin, FruitSaladField ); - /** @brief skin definition for the Dish - * - * Nothing meaningful to be documented here beyond copy and paste from other skin in classes.h - */ - SOASKIN_TRIVIAL( DishSkin, DishField ); - - /** @brief skin definition for the FruitSalad and Dish - * - * Nothing meaningful to be documented here beyond copy and paste from other skin in classes.h - */ - SOASKIN_TRIVIAL( FullPlateSkin, FruitSaladField, DishField ); - -} // namespace Examples diff --git a/Kernel/SOAExtensions/src/ZipBarrierGatherer.cpp b/Kernel/SOAExtensions/src/ZipBarrierGatherer.cpp deleted file mode 100644 index 5ab4880ccee..00000000000 --- a/Kernel/SOAExtensions/src/ZipBarrierGatherer.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ - -#include "GaudiAlg/FunctionalDetails.h" // VOC -#include "GaudiAlg/MergingTransformer.h" -#include "GaudiAlg/Transformer.h" -#include "SOAExtensions/ZipSelection.h" - -/** @class ZipBarrierGatherer ZipBarrierGatherer.cpp - * - * The Gatherer takes multiple optional input-containers (LHCb::Tracks for - * instance) (selections from different lines) and puts them into one big - * vector. This "only" creates vector of selection, i.e. not one big - * selection, this seemingly pointless step needs to be done before the - * ZipBarrierMerger because of the particularities of how the functional - * framework works. - * - * This algorithm is globally usable. It is not for the purpose of the - * SOAExtensions barrier example. It can gather selections of integer, tracks, - * particles, ... as long as they are in the SOAExtensions framework. - * - * @brief gather multiple Zipping::ExportedSelection for processing in ZipBarrierMerger - */ -struct ZipBarrierGatherer final - : Gaudi::Functional::MergingTransformer< - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*>( - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> const& )> { - - ZipBarrierGatherer( std::string const& name, ISvcLocator* pSvcLocator ) - : Gaudi::Functional::MergingTransformer< - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*>( - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> const& )>( - name, pSvcLocator, {"InputSelections", {"/Event/SelectAll"}}, - {"OutputSelection", {"/Event/GatheredSelects"}} ) {} - - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> operator()( - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> const& vec ) const override { - return vec; - } -}; - -DECLARE_COMPONENT( ZipBarrierGatherer ) diff --git a/Kernel/SOAExtensions/src/ZipBarrierMerger.cpp b/Kernel/SOAExtensions/src/ZipBarrierMerger.cpp deleted file mode 100644 index f4b35b87c98..00000000000 --- a/Kernel/SOAExtensions/src/ZipBarrierMerger.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ - -#include "GaudiAlg/FunctionalDetails.h" // VOC -#include "GaudiAlg/Transformer.h" -#include "SOAExtensions/ZipSelection.h" -#include <iterator> // std::iterator_traits -#include <type_traits> - -/** @file - * ZipBarrier algorithms: - * - * - The Gatherer takes multiple optional input-containers (LHCb::Tracks for - * instance) (selections from different lines) and puts them into one big - * vector - * - * - The Merger creates the union of all those containers to have one container - * where some shared algorithm can loop over (implemented for - * Keyed(SharedObject)Containers and Masks (with integral types of values 0 - * and 1) - * - * - The next ZipBarrier step is some shared algorithm, taking the output of the - * merger (and in case of masks some other data) as input - * - * - The scatterer takes the output of the shared algorithm + the gatherer - * output + merger output how to scatter the inputs to the different lines - * again - */ - -/** @class ZipBarrierMerger ZipBarrierMerger.cpp - * - * The Merger creates the union of all those containers to have one container - * where some shared algorithm can loop over (implemented for - * Keyed(SharedObject)Containers and Masks (with integral types of values 0 and 1) - * - */ - -struct ZipBarrierMerger final - : public Gaudi::Functional::Transformer<Zipping::ExportedSelection<>( - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> const& )> { - - ZipBarrierMerger( std::string const& name, ISvcLocator* pSvcLocator ) - : Gaudi::Functional::Transformer<Zipping::ExportedSelection<>( - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> const& )>( - name, pSvcLocator, {"InputSelection", "/Event/GatheredSelects"}, - {"OutputSelection", "/Event/MergedSelects"} ) {} - - Zipping::ExportedSelection<> operator()( - Gaudi::Functional::details::vector_of_const_<const Zipping::ExportedSelection<>*> const& vec ) const override { - // this only works thanks to the above iterator_traits. - // the loop searches for the first not-nullptr as entry point for merging. - // iter is an iterator of a container of pointers to containers. - // entry is the dereferenced iterator, i.e. a pointer to a container, the pointer is NULL if the container doesn't - // exist. - auto iter = std::find_if( vec.begin(), vec.end(), []( auto* entry ) { return entry; } ); - - if ( iter == vec.end() ) { - throw GaudiException( std::string( "No single input into ZipBarrierMerger, " - "shouldn't have been scheduled." ), - Zipping::details::typename_v<decltype( *this )>, StatusCode::FAILURE ); - } - - // init should be copy constructed from a const Zipping::ExportedSelection<unsigned short> - static_assert( std::is_same_v<decltype( *iter ), const Zipping::ExportedSelection<>*>, "message" ); - auto init = **iter; - // this somewhat violates what the C++ standard expects an accumulate lambda to be (commutative in a and b) but it - // is common practise to have different types for iterated item and accumulator. - return std::accumulate( ++iter, vec.end(), init, - []( Zipping::ExportedSelection<> const& a, - Zipping::ExportedSelection<> const* b ) -> Zipping::ExportedSelection<> { - if ( b ) return set_union( a, *b ); - return a; - } ); - } -}; - -DECLARE_COMPONENT( ZipBarrierMerger ) diff --git a/Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/apples.qmt b/Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/apples.qmt deleted file mode 100644 index 4845dd65707..00000000000 --- a/Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/apples.qmt +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- - (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration - - This software is distributed under the terms of the GNU General Public - Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". - - In applying this licence, CERN does not waive the privileges and immunities - granted to it by virtue of its status as an Intergovernmental Organization - or submit itself to any jurisdiction. ---> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# Author: pseyfert -# Purpose: Run the example of Kernel/SOAExtensions -# Prerequisites: Successful build of Kernel/SOAExtensions and LHCb runtime environment -####################################################### ---> -<extension class="SOAExtensions.apples_example" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set><text>$SOAEXTENSIONSROOT/examples/options/apples_1.py</text></set></argument> -<argument name="use_temp_dir"><enumeral>true</enumeral></argument> -<argument name="validator"><text> -countErrorLines() -</text></argument> -</extension> - diff --git a/Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/barrier.qmt b/Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/barrier.qmt deleted file mode 100644 index 85bdfa3be9c..00000000000 --- a/Kernel/SOAExtensions/tests/qmtest/soaextensions.qms/barrier.qmt +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- - (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration - - This software is distributed under the terms of the GNU General Public - Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". - - In applying this licence, CERN does not waive the privileges and immunities - granted to it by virtue of its status as an Intergovernmental Organization - or submit itself to any jurisdiction. ---> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# Author: pseyfert -# Purpose: Test the barrier with ZipSelections -# Prerequisites: Working AnyData and MergingTransformer framework from Gaudi and set operations on ZipSelections -####################################################### ---> -<extension class="SOAExtensions.barrier_example" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set><text>$SOAEXTENSIONSROOT/examples/options/BarrierExamples.py</text></set></argument> -<argument name="use_temp_dir"><enumeral>true</enumeral></argument> -<argument name="validator"><text> -countErrorLines() -</text></argument> -</extension> - diff --git a/Kernel/SOAExtensions/tests/src/TestSelection.cpp b/Kernel/SOAExtensions/tests/src/TestSelection.cpp deleted file mode 100644 index 38cbc676f4f..00000000000 --- a/Kernel/SOAExtensions/tests/src/TestSelection.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2019 CERN for the benefit of the LHCb collaboration - * Author: Paul Seyfert <pseyfert@cern.ch> - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENSE". - * - * In applying this licence, CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ -#define ZIPPING_SEMANTIC_CHECKS - -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE utestSelection -#include "SOAContainer/SOAContainer.h" // for Container -#include "SOAContainer/SOASkin.h" // for SOASkinCreatorSimple<>::type -#include "SOAContainer/SOAView.h" // for _View<>::reference, _View -#include "SOAExtensions/ZipAlgorithms.h" // for transform -#include "SOAExtensions/ZipContainer.h" // for ZipContainer, semantic_zip -#include "SOAExtensions/ZipSelection.h" // for SelectionView, SelectionVi... -#include <boost/test/unit_test.hpp> -// #include <boost/test/execution_monitor.hpp> -#include <memory> // for allocator, allocator_trait... -#include <string> // for operator<<, string -#include <utility> // for move -#include <vector> // for vector - -#include "SOAContainer/SOAField.h" -#include "SOAContainer/SOASkin.h" -#include "SOAContainer/SOAUtils.h" -#include "SOAContainer/SOAView.h" - -struct track { - float x; - float y; - float z; - float tx; - float ty; - friend bool operator==( const track& lhs, const track& rhs ) { return &lhs == &rhs; } - friend bool operator!=( const track& lhs, const track& rhs ) { return &lhs != &rhs; } - friend std::ostream& operator<<( std::ostream& stream, const track& t ) { - char buf[100]; - snprintf( buf, 99, "track at (%#8.2f, %#8.2f, %#8.2f)", t.x, t.y, t.z ); - stream << buf; - return stream; - } -}; - -SOAFIELD_TRIVIAL( f_track, accessor_track, track ); -SOASKIN_TRIVIAL( s_track, f_track ); - -struct fitres { - float px; - float py; - float pz; - int q; - friend bool operator==( const fitres& lhs, const fitres& rhs ) { return &lhs == &rhs; } - friend bool operator!=( const fitres& lhs, const fitres& rhs ) { return &lhs != &rhs; } - friend std::ostream& operator<<( std::ostream& stream, const fitres& t ) { - char buf[100]; - snprintf( buf, 99, "momentum = (%#8.2f, %#8.2f, %#8.2f), charge %d", t.px, t.py, t.pz, t.q ); - stream << buf; - return stream; - } -}; - -SOAFIELD_TRIVIAL( f_fitres, accessor_fitres, fitres ); -SOASKIN_TRIVIAL( s_fitres, f_fitres ); - -struct fitqual { - float chi2; - int dof; - friend bool operator==( const fitqual& lhs, const fitqual& rhs ) { - return lhs.dof == rhs.dof && ( ( std::abs( lhs.chi2 - rhs.chi2 ) / ( lhs.chi2 + rhs.chi2 ) < 0.01 ) || - ( std::abs( lhs.chi2 ) < 0.01 && std::abs( rhs.chi2 ) < 0.01 ) ); - } - friend std::ostream& operator<<( std::ostream& stream, const fitqual& t ) { - char buf[100]; - snprintf( buf, 99, "chi2/dof = %#8.2f/%d = %#8.4f", t.chi2, t.dof, t.chi2 / ( (float)t.dof ) ); - stream << buf; - return stream; - } -}; - -SOAFIELD_TRIVIAL( f_fitqual, accessor_fitqual, fitqual ); -SOASKIN_TRIVIAL( s_fitqual, f_fitqual ); - -/// pythonic sugar -#include "range/v3/all.hpp" // IWYU pragma: keep -// IWYU pragma : no_include <range/v3/view/indices.hpp> -// IWYU pragma : no_include <range/v3/view/take_exactly.hpp> -auto range = ranges::views::indices; -/// end of sugar - -BOOST_AUTO_TEST_CASE( basic_zip_and_selection_operations ) { - Zipping::ZipContainer<SOA::Container<std::vector, s_track>> foo1; - Zipping::ZipContainer<SOA::Container<std::vector, s_track>> foo1_alt; - Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo2( foo1.zipIdentifier() ); - Zipping::ZipContainer<SOA::Container<std::vector, s_fitqual>> foo3( foo1.zipIdentifier() ); - for ( auto i : range( 42 ) ) { - track t{i * 100.f, i * 2.f, ( 42 - i ) * 100.f, 0.f, 0.f}; - foo1.push_back( t ); - foo2.push_back( fitres{0.f, 0.f, i * 100.f, i} ); - foo3.push_back( fitqual{0.f, i} ); - } - - BOOST_CHECK_THROW( Zipping::semantic_zip( foo1_alt, foo2 ), Zipping::IncompatibleZipException ); - auto track_with_momentum = Zipping::semantic_zip( foo1, foo2 ); - [[maybe_unused]] auto full_track = Zipping::semantic_zip( foo1, foo2, foo3 ); - [[maybe_unused]] auto another_full_track = Zipping::semantic_zip( track_with_momentum, foo3 ); - [[maybe_unused]] auto yet_another_full_track = Zipping::semantic_zip( full_track ); - - BOOST_CHECK_EQUAL( full_track[0], ( *full_track.begin() ) ); - - auto exported_selection = - Zipping::makeSelection( &track_with_momentum, []( auto i ) { return 0 == i.accessor_fitres().q % 2; } ); - - Zipping::SelectionView selected_tracks{&track_with_momentum, exported_selection}; - - Zipping::SelectionView selected_full_tracks( &full_track, exported_selection ); - - auto crosscheck = selected_full_tracks.export_selection(); - - BOOST_CHECK( crosscheck == exported_selection ); - - [[maybe_unused]] auto refined = - selected_full_tracks.select( []( const auto fulltrack ) { return fulltrack.accessor_fitqual().chi2 < 3; } ); - - BOOST_CHECK_EQUAL( selected_tracks.size(), track_with_momentum.size() / 2 ); - - BOOST_CHECK_EQUAL( *selected_tracks.begin(), selected_tracks.front() ); - BOOST_CHECK_EQUAL( *( selected_tracks.end() - 1 ), selected_tracks.back() ); - - int keep_track = 0; - for ( auto it = selected_full_tracks.begin(); it != selected_full_tracks.end(); ++it ) { - BOOST_CHECK_EQUAL( ( *it ).accessor_fitres().q, 2 * keep_track ); - BOOST_CHECK_EQUAL( it - selected_full_tracks.begin(), keep_track ); - - BOOST_CHECK( ( *it ) == selected_full_tracks[keep_track] ); - BOOST_CHECK_EQUAL( *it, selected_full_tracks[keep_track] ); - BOOST_CHECK_EQUAL( selected_full_tracks[keep_track], selected_full_tracks[keep_track] ); - keep_track += 1; - } - keep_track = 0; - for ( auto proxy : selected_tracks ) { BOOST_CHECK_EQUAL( proxy, selected_tracks[keep_track++] ); } - BOOST_CHECK( std::all_of( track_with_momentum.begin(), track_with_momentum.end(), []( auto t ) { - return std::abs( t.accessor_track().x + t.accessor_track().z - 4200.f ) < 50.f; - } ) ); - - int sum_of_Q = 0; - for ( size_t i = 0; i < selected_tracks.size(); ++i ) sum_of_Q += selected_tracks[i].accessor_fitres().q; - - std::for_each( selected_tracks.begin(), selected_tracks.end(), - [&sum_of_Q]( auto t ) { sum_of_Q -= t.accessor_fitres().q; } ); - - BOOST_CHECK_EQUAL( sum_of_Q, 0 ); - - BOOST_CHECK_EQUAL( std::count( track_with_momentum.begin(), track_with_momentum.end(), selected_tracks[2] ), 1 ); - - BOOST_CHECK_EQUAL( std::count_if( track_with_momentum.begin(), track_with_momentum.end(), - []( auto t ) { return t.accessor_fitres().q % 2 == 0; } ), - selected_tracks.size() ); - - BOOST_CHECK( std::is_sorted( track_with_momentum.begin(), track_with_momentum.end(), - []( auto t1, auto t2 ) { return t1.accessor_fitres().py < t2.accessor_fitres().py; } ) ); -} - -BOOST_AUTO_TEST_CASE( stlalgs ) { - Zipping::ZipContainer<SOA::Container<std::vector, s_track>> foo1; - Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo2( foo1.zipIdentifier() ); - Zipping::ZipContainer<SOA::Container<std::vector, s_fitqual>> foo3( foo1.zipIdentifier() ); - for ( auto i : range( 42 ) ) { - track t{i * 100.f, i * 2.f, ( 42 - i ) * 100.f, 0.f, 0.f}; - foo1.push_back( t ); - foo2.push_back( fitres{0.f, 0.f, i * 100.f, i} ); - foo3.push_back( fitqual{0.f, i} ); - } - - auto foo_all = Zipping::semantic_zip( foo1, foo2, foo3 ); - Zipping::ExportedSelection<> e = - Zipping::makeSelection( &foo_all, []( auto f ) { return f.accessor_fitres().q % 2 == 0; } ); - Zipping::SelectionView foo_sel( &foo_all, e ); - - auto found = std::find( foo_all.begin(), foo_all.end(), foo_all[3] ); - BOOST_CHECK_NE( found, foo_all.end() ); - - auto founds = std::find( foo_sel.begin(), foo_sel.end(), foo_sel[2] ); - BOOST_CHECK( founds != foo_sel.end() ); - - found = std::find( foo_all.begin(), foo_all.end(), foo_sel[2] ); - BOOST_CHECK_NE( found, foo_all.end() ); - - for ( auto selected_element : foo_sel ) { - found = std::find( foo_all.begin(), foo_all.end(), selected_element ); - BOOST_CHECK_NE( found, foo_all.end() ); - } - bool prev = true; - bool init = false; - for ( auto element : foo_all ) { - bool found_ = ( foo_sel.end() == std::find( foo_sel.begin(), foo_sel.end(), element ) ); - if ( !init ) prev = !found_; - BOOST_CHECK_NE( found_, prev ); - prev = found_; - } -} - -BOOST_AUTO_TEST_CASE( set_operations ) { - Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo2; - Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo2_alt; - for ( auto i : range( 42 ) ) { - foo2.push_back( fitres{0.f, 0.f, i * 100.f, i} ); - foo2_alt.push_back( fitres{0.f, 0.f, i * 100.f, i} ); - } - - Zipping::ExportedSelection<> sel1 = - Zipping::makeSelection( &foo2, []( auto i ) { return 0 == i.accessor_fitres().q % 2; } ); - Zipping::ExportedSelection<> sel2 = - Zipping::makeSelection( &foo2, []( auto i ) { return 0 == i.accessor_fitres().q % 3; } ); - Zipping::ExportedSelection<> sel1_alt = - Zipping::makeSelection( &foo2_alt, []( auto i ) { return 0 == i.accessor_fitres().q % 2; } ); - - auto commahider = [&]( auto sel ) { return Zipping::SelectionView{&foo2, sel}; }; - - BOOST_CHECK_THROW( commahider( sel1_alt ), GaudiException ); - - Zipping::SelectionView tmp( &foo2, sel1 ); - - auto union_ = set_union( sel1, sel2 ); - auto intersection = set_intersection( sel1, sel2 ); - auto symdiff = set_symmetric_difference( sel1, sel2 ); - - auto commahider2 = [&]() { return set_union( sel2, sel1_alt ); }; - - BOOST_CHECK_THROW( commahider2(), GaudiException ); - BOOST_CHECK( includes( sel1, intersection ) ); -} - -BOOST_AUTO_TEST_CASE( transform ) { - Zipping::ZipContainer<SOA::Container<std::vector, s_track>> foo1; - for ( auto i : range( 42 ) ) { - track t{i * 100.f, i * 2.f, ( 42 - i ) * 100.f, 0.f, 0.f}; - foo1.push_back( t ); - } - Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo2 = Zipping::transform<s_fitres>( - foo1, []( Zipping::ZipContainer<SOA::Container<std::vector, s_track>>::proxy track ) { - return fitres{track.accessor_track().x, track.accessor_track().y, track.accessor_track().z, - (int)track.accessor_track().y}; - } ); - - auto zip = Zipping::semantic_zip( foo1, foo2 ); - - auto foo3 = Zipping::transform<s_fitqual, std::vector>( zip, []( auto proxy ) { - return fitqual{proxy.accessor_track().x, proxy.accessor_fitres().q}; - } ); - - BOOST_CHECK( areSemanticallyCompatible( foo1, foo2, foo3 ) ); - BOOST_CHECK_EQUAL( foo1.size(), foo2.size() ); - BOOST_CHECK_EQUAL( foo1.size(), foo3.size() ); - - auto exported_selection = - Zipping::makeSelection( &foo1, []( auto i ) -> bool { return i.accessor_track().x < 550.f; } ); - - Zipping::SelectionView view1{&foo1, exported_selection}; - - [[maybe_unused]] Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo4 = Zipping::transform<s_fitres>( - foo1, - []( Zipping::ZipContainer<SOA::Container<std::vector, s_track>>::proxy track ) { - return fitres{track.accessor_track().x, track.accessor_track().y, track.accessor_track().z, - (int)track.accessor_track().y}; - }, - exported_selection ); - - [[maybe_unused]] Zipping::ZipContainer<SOA::Container<std::vector, s_fitres>> foo5 = - Zipping::transform<s_fitres, std::vector>( - zip, - []( auto track ) { - return fitres{track.accessor_track().x, track.accessor_track().y, track.accessor_track().z, - (int)track.accessor_track().y}; - }, - exported_selection ); - - [[maybe_unused]] auto foo6 = Zipping::transform<s_fitres, std::vector>( view1, []( auto track ) { - return fitres{track.accessor_track().x, track.accessor_track().y, track.accessor_track().z, - (int)track.accessor_track().y}; - } ); - - auto zip2 = Zipping::semantic_zip( foo1, foo6 ); - Zipping::SelectionView view2{&zip2, exported_selection}; - - for ( auto element : view2 ) { BOOST_CHECK_EQUAL( (int)element.accessor_track().y, element.accessor_fitres().q ); } -} diff --git a/Kernel/SOAExtensions/tests/src/hana_soa_access.cpp b/Kernel/SOAExtensions/tests/src/hana_soa_access.cpp deleted file mode 100644 index 3f55daa175f..00000000000 --- a/Kernel/SOAExtensions/tests/src/hana_soa_access.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ -#undef NDEBUG - -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE utestSelection -#include <boost/test/unit_test.hpp> - -#include "LHCbMath/SIMDWrapper.h" -#include <boost/hana.hpp> -#include <functional> -#include <vector> - -namespace hana = boost::hana; - -using namespace SIMDWrapper::avx2; - -template <typename T> -struct type_; // for type checking - -template <typename T> -auto _get_members( T&& t ) { - return hana::transform( hana::accessors<std::decay_t<T>>(), - [&t]( auto accessor ) -> decltype( auto ) { return &hana::second( accessor )( t ); } ); -} - -template <typename T> -struct _first_member_type { - using type = - std::remove_pointer_t<std::remove_reference_t<decltype( _get_members( std::declval<T>() )[hana::size_c<0>] )>>; -}; - -template <typename T> -using _first_member_type_t = typename _first_member_type<T>::type; - -template <typename T> -struct _is_simd_wrapper { // to be extended by all simd types - constexpr static bool value = std::is_same_v<int_v, T> or std::is_same_v<float_v, T>; -}; - -template <typename Out, typename T> -Out get( T&& t, int i ) { - auto construct = []( auto&&... ts ) -> decltype( auto ) { return Out{ts...}; }; - - using _out_mem_t = _first_member_type_t<Out>; - auto aos = hana::transform( _get_members( t ), [i]( auto* item ) -> decltype( auto ) { - if constexpr ( std::is_pointer_v<_out_mem_t> ) { - return &( *item )[i]; - } else if constexpr ( _is_simd_wrapper<_out_mem_t>::value ) { - return &( *item )[i]; - } else { - return ( *item )[i]; - } - } ); - return hana::unpack( aos, construct ); -} - -struct muonpids { - BOOST_HANA_DEFINE_STRUCT( muonpids, ( std::vector<int>, statuss ), ( std::vector<float>, chi2corrs ) ); -}; - -struct muonpid_ptr { // with pointers to the original structure - BOOST_HANA_DEFINE_STRUCT( muonpid_ptr, ( int*, status ), ( float*, chi2corr ) ); -}; - -struct muonpid { // copies of original structure - BOOST_HANA_DEFINE_STRUCT( muonpid, ( int, status ), ( float, chi2corr ) ); -}; - -struct muonpid_soa { // now i want fancy soa types - BOOST_HANA_DEFINE_STRUCT( muonpid_soa, ( int_v, status ), ( float_v, chi2corr ) ); -}; - -BOOST_AUTO_TEST_CASE( all ) { - muonpids m{{1, 2, 3, 4, 5, 6, 7, 0}, {3, 4, 5, 6, 7, 0, 1, 2}}; - - // check ptr types - auto a = get<muonpid_ptr>( m, 1 ); - *a.status = 42; - *a.chi2corr = 100; - BOOST_CHECK( m.statuss[1] == 42 and m.chi2corrs[1] == 100 ); - - // check value types - auto b = get<muonpid>( m, 2 ); - BOOST_CHECK( b.status == 3 and b.chi2corr == 5 ); - -// check vector types -#ifdef __AVX2__ - auto c = get<muonpid_soa>( m, 0 ); - BOOST_STATIC_ASSERT( std::is_same_v<decltype( c.status ), int_v> ); - BOOST_STATIC_ASSERT( std::is_same_v<decltype( c.chi2corr ), float_v> ); - int sum_chi2corr = c.chi2corr.hadd(); - - BOOST_CHECK_MESSAGE( sum_chi2corr == 124, sizeof( c.status ) ); -#endif -} -- GitLab