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_sizeandoperator()consecutively. - Input and outputs are
[const] std::vectorsof the underlying Allen type. The exception isbool, which instead usesstd::vector<char>as backend to avoidstd::vectorbool 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_algorithmsgenerates 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_tproperty of all algorithms has nowpublicvisibility 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.cppwrappers). - Added two new Gaudi algorithms under
Rec/Allen/:ProvideConstantsandProvideRuntimeOptions. These two algorithms are required in any invocation to a wrapper algorithm. - Added two new Gaudi algorithms for data conversions:
GaudiAllenVeloToV2TracksandGaudiAllenForwardToV2Tracks. These two algorithms convert Allen data received in the form ofstd::vectorsto v2 tracks. - Two types of algorithms can be generated:
ConsumerandMultiTransformer. All AllenProduceralgorithms becomeMultiTransformersince they now require aconstantsandruntime_optionsparameter. - Moved
configuration/sequences/AllenConftoconfiguration/python/AllenConf. - Created
Rec/Allen/python/AllenCore/generator.pywhich providesmake_algorithmin Gaudi. - Created
Rec/Allen/python/AllenConf/algorithms.pywhich acts as a proxy forPyConf.Algorithms. - Packages
configurationandRec/Allenexport now theirpythondirectory 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_buffersin 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).