Generation of Gaudi wrapper algorithms for Allen algorithms
This MR produces automatic Gaudi wrappers to all Allen algorithms when Allen is compiled in non-STANDALONE mode.
- Automatic algorithm wrappers are generated for all Allen algorithms.
- Gaudi versions of Allen algorithms invoke the Allen algorithms'
set_arguments_size
andoperator()
consecutively. - Input and outputs are
[const] std::vectors
of the underlying Allen type. The exception isbool
, which instead usesstd::vector<char>
as backend to avoidstd::vector
bool storage shenanigans. - Properties are properly populated in the Gaudi wrappers, initialized to the same (parsed) Allen defaults upon initialization.
What this enables in short
All Allen configurations introduced with the MES are now usable from within Gaudi, and all Allen algorithms are now usable as Gaudi algorithms.
A Gaudi configuration like the following is now possible. It works both in Allen and Gaudi:
from AllenConf.hlt1_reconstruction import hlt1_reconstruction
hlt1_reco = hlt1_reconstruction()
velo_tracks = hlt1_reco['velo_tracks']
ut_tracks = hlt1_reco['ut_tracks']
forward_tracks = hlt1_reco['forward_tracks']
kf_tracks = hlt1_reco['kalman_velo_only']
Here is an example of such a configuration.
This works because all Allen algorithms are translated to Gaudi algorithms with automatically compile-time generated wrappers. In addition, the following two python paths are installed as part of Allen:
- https://gitlab.cern.ch/lhcb/Allen/-/tree/dcampora_nnolte_gaudi_conversion/configuration/python
- https://gitlab.cern.ch/lhcb/Allen/-/tree/dcampora_nnolte_gaudi_conversion/Rec/Allen/python
The above only occurs when Allen is compiled with -DSTANDALONE=OFF
, so the STANDALONE
build is not affected.
List of changes
- At configure-time the list of algorithm wrappers that will be built is generated.
- A new custom CMake target
gaudi_wrappers_of_allen_algorithms
generates Gaudi wrappers of Allen algorithms (see below for an example). - The generation of Gaudi wrappers is only triggered if building with
-DSTANDALONE=OFF
. - The
verbosity_t
property of all algorithms has nowpublic
visibility to allow Gaudi algorithms access. - Added a new function
set_property_value(const R& value)
to Allen Algorithm class. - Implemented parsing of default datatypes of Allen algorithms.
- Refactored
ParseAlgorithms.py
. Now it accepts three possible generations with option--generate
:views
(default, generates the Python view of all Allen algorithms),wrapperlist
(which generates the list of files used at configure-time) andwrappers
(which generates.cpp
wrappers). - Added two new Gaudi algorithms under
Rec/Allen/
:ProvideConstants
andProvideRuntimeOptions
. These two algorithms are required in any invocation to a wrapper algorithm. - Added two new Gaudi algorithms for data conversions:
GaudiAllenVeloToV2Tracks
andGaudiAllenForwardToV2Tracks
. These two algorithms convert Allen data received in the form ofstd::vectors
to v2 tracks. - Two types of algorithms can be generated:
Consumer
andMultiTransformer
. All AllenProducer
algorithms becomeMultiTransformer
since they now require aconstants
andruntime_options
parameter. - Moved
configuration/sequences/AllenConf
toconfiguration/python/AllenConf
. - Created
Rec/Allen/python/AllenCore/generator.py
which providesmake_algorithm
in Gaudi. - Created
Rec/Allen/python/AllenConf/algorithms.py
which acts as a proxy forPyConf.Algorithms
. - Packages
configuration
andRec/Allen
export now theirpython
directory usinggaudi_install_python_modules
.
Functionality this enables
- This MR streamlines the creation of Gaudi tests for Allen algorithms.
- It allows the creation of subsequences that run as independent algorithms.
- Concretely, all Allen-to-Gaudi conversions can now become proper Gaudi algorithms.
- It is a step to removing
host_buffers
in all Allen algorithms, which was required to persist objects after the Allen sequence was run.
Example - Search by triplet generated conversion
#include "AlgorithmConversionTools.h"
#include </home/nnolte/lb-stack-setup/stack5/Allen/device/velo/search_by_triplet/include/SearchByTriplet.cuh>
#include <GaudiAlg/Transformer.h>
#include <vector>
// output type
using output_t = std::tuple<
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_tracks_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_tracklets_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_tracks_to_follow_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_three_hit_tracks_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_hit_used_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_atomics_velo_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_rel_indices_t>,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_number_of_velo_tracks_t>>;
// algorithm definition
struct velo_search_by_triplet_t_gaudi final
: Gaudi::Functional::MultiTransformer<output_t(
Allen::parameter_vector<velo_search_by_triplet::Parameters::host_number_of_events_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::host_total_number_of_velo_clusters_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_event_list_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_number_of_events_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_sorted_velo_cluster_container_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_offsets_estimated_input_size_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_module_cluster_num_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_hit_phi_t> const&,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_velo_clusters_t> const&,
const RuntimeOptions&,
Constants const* const&)> {
// wrapped algorithm body
velo_search_by_triplet_t_gaudi(std::string const& name, ISvcLocator* pSvc) :
MultiTransformer(
name,
pSvc,
{KeyValue("host_number_of_events_t", {""}),
KeyValue("host_total_number_of_velo_clusters_t", {""}),
KeyValue("dev_event_list_t", {""}),
KeyValue("dev_number_of_events_t", {""}),
KeyValue("dev_sorted_velo_cluster_container_t", {""}),
KeyValue("dev_offsets_estimated_input_size_t", {""}),
KeyValue("dev_module_cluster_num_t", {""}),
KeyValue("dev_hit_phi_t", {""}),
KeyValue("dev_velo_clusters_t", {""}),
KeyValue("runtime_options_t", {""}),
KeyValue("constants_t", {""})},
{KeyValue("dev_tracks_t", {""}),
KeyValue("dev_tracklets_t", {""}),
KeyValue("dev_tracks_to_follow_t", {""}),
KeyValue("dev_three_hit_tracks_t", {""}),
KeyValue("dev_hit_used_t", {""}),
KeyValue("dev_atomics_velo_t", {""}),
KeyValue("dev_rel_indices_t", {""}),
KeyValue("dev_number_of_velo_tracks_t", {""})})
{}
// operator()
output_t operator()(
Allen::parameter_vector<velo_search_by_triplet::Parameters::host_number_of_events_t> const&
host_number_of_events_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::host_total_number_of_velo_clusters_t> const&
host_total_number_of_velo_clusters_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_event_list_t> const& dev_event_list_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_number_of_events_t> const&
dev_number_of_events_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_sorted_velo_cluster_container_t> const&
dev_sorted_velo_cluster_container_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_offsets_estimated_input_size_t> const&
dev_offsets_estimated_input_size_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_module_cluster_num_t> const&
dev_module_cluster_num_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_hit_phi_t> const& dev_hit_phi_t_arg,
Allen::parameter_vector<velo_search_by_triplet::Parameters::dev_velo_clusters_t> const& dev_velo_clusters_t_arg,
const RuntimeOptions& runtime_options,
Constants const* const& constants) const override
{
output_t output_container {};
// TES wrappers
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::host_number_of_events_t>
host_number_of_events_t_wrapper {host_number_of_events_t_arg, "host_number_of_events_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::host_total_number_of_velo_clusters_t>
host_total_number_of_velo_clusters_t_wrapper {
host_total_number_of_velo_clusters_t_arg, "host_total_number_of_velo_clusters_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_event_list_t> dev_event_list_t_wrapper {
dev_event_list_t_arg, "dev_event_list_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_number_of_events_t> dev_number_of_events_t_wrapper {
dev_number_of_events_t_arg, "dev_number_of_events_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_sorted_velo_cluster_container_t>
dev_sorted_velo_cluster_container_t_wrapper {
dev_sorted_velo_cluster_container_t_arg, "dev_sorted_velo_cluster_container_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_offsets_estimated_input_size_t>
dev_offsets_estimated_input_size_t_wrapper {
dev_offsets_estimated_input_size_t_arg, "dev_offsets_estimated_input_size_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_module_cluster_num_t>
dev_module_cluster_num_t_wrapper {dev_module_cluster_num_t_arg, "dev_module_cluster_num_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_hit_phi_t> dev_hit_phi_t_wrapper {
dev_hit_phi_t_arg, "dev_hit_phi_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_tracks_t> dev_tracks_t_wrapper {
std::get<0>(output_container), "dev_tracks_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_tracklets_t> dev_tracklets_t_wrapper {
std::get<1>(output_container), "dev_tracklets_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_tracks_to_follow_t> dev_tracks_to_follow_t_wrapper {
std::get<2>(output_container), "dev_tracks_to_follow_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_three_hit_tracks_t> dev_three_hit_tracks_t_wrapper {
std::get<3>(output_container), "dev_three_hit_tracks_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_hit_used_t> dev_hit_used_t_wrapper {
std::get<4>(output_container), "dev_hit_used_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_atomics_velo_t> dev_atomics_velo_t_wrapper {
std::get<5>(output_container), "dev_atomics_velo_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_rel_indices_t> dev_rel_indices_t_wrapper {
std::get<6>(output_container), "dev_rel_indices_t"};
Allen::TESWrapperOutput<velo_search_by_triplet::Parameters::dev_number_of_velo_tracks_t>
dev_number_of_velo_tracks_t_wrapper {std::get<7>(output_container), "dev_number_of_velo_tracks_t"};
Allen::TESWrapperInput<velo_search_by_triplet::Parameters::dev_velo_clusters_t> dev_velo_clusters_t_wrapper {
dev_velo_clusters_t_arg, "dev_velo_clusters_t"};
// Inputs to set_arguments_size and operator()
std::array<std::reference_wrapper<ArgumentData>, 17> tes_wrappers_references {
host_number_of_events_t_wrapper,
host_total_number_of_velo_clusters_t_wrapper,
dev_event_list_t_wrapper,
dev_number_of_events_t_wrapper,
dev_sorted_velo_cluster_container_t_wrapper,
dev_offsets_estimated_input_size_t_wrapper,
dev_module_cluster_num_t_wrapper,
dev_hit_phi_t_wrapper,
dev_tracks_t_wrapper,
dev_tracklets_t_wrapper,
dev_tracks_to_follow_t_wrapper,
dev_three_hit_tracks_t_wrapper,
dev_hit_used_t_wrapper,
dev_atomics_velo_t_wrapper,
dev_rel_indices_t_wrapper,
dev_number_of_velo_tracks_t_wrapper,
dev_velo_clusters_t_wrapper};
HostBuffers host_buffers {};
Allen::Context context {};
// set arguments size invocation
m_algorithm.set_arguments_size(tes_wrappers_references, runtime_options, *constants, host_buffers);
// algorithm operator() invocation
m_algorithm(tes_wrappers_references, runtime_options, *constants, host_buffers, context);
return output_container;
}
private:
velo_search_by_triplet::velo_search_by_triplet_t m_algorithm {};
Gaudi::Property<int> m_verbosity_t {
this,
"verbosity",
3,
[=](auto&) { m_algorithm.set_property_value<Allen::Algorithm::verbosity_t, int>(m_verbosity_t.value()); },
Gaudi::Details::Property::ImmediatelyInvokeHandler {true},
"verbosity of algorithm"};
Gaudi::Property<float> m_phi_tolerance_t {
this,
"phi_tolerance",
0.045f,
[=](auto&) {
m_algorithm.set_property_value<velo_search_by_triplet::Parameters::phi_tolerance_t, float>(
m_phi_tolerance_t.value());
},
Gaudi::Details::Property::ImmediatelyInvokeHandler {true},
"tolerance in phi"};
Gaudi::Property<float> m_max_scatter_t {
this,
"max_scatter",
0.08f,
[=](auto&) {
m_algorithm.set_property_value<velo_search_by_triplet::Parameters::max_scatter_t, float>(m_max_scatter_t.value());
},
Gaudi::Details::Property::ImmediatelyInvokeHandler {true},
"maximum scatter for seeding and forwarding"};
Gaudi::Property<unsigned int> m_max_skipped_modules_t {
this,
"max_skipped_modules",
1,
[=](auto&) {
m_algorithm.set_property_value<velo_search_by_triplet::Parameters::max_skipped_modules_t, unsigned int>(
m_max_skipped_modules_t.value());
},
Gaudi::Details::Property::ImmediatelyInvokeHandler {true},
"skipped modules"};
Gaudi::Property<unsigned int> m_block_dim_x_t {
this,
"block_dim_x",
64,
[=](auto&) {
m_algorithm.set_property_value<velo_search_by_triplet::Parameters::block_dim_x_t, unsigned int>(
m_block_dim_x_t.value());
},
Gaudi::Details::Property::ImmediatelyInvokeHandler {true},
"block dimension x"};
};
DECLARE_COMPONENT(velo_search_by_triplet_t_gaudi)
This MR is built on top of !393 (merged) and !429 (merged).
Should go together with Moore!609 (merged).