diff --git a/Rec/Allen/src/RunAllen.cpp b/Rec/Allen/src/RunAllen.cpp index 06f94252c9dc58d6649a5fb04427688a9523d751..800ed6b3ff028d6cc2b94ee9dfe3fd30c980999a 100644 --- a/Rec/Allen/src/RunAllen.cpp +++ b/Rec/Allen/src/RunAllen.cpp @@ -129,9 +129,9 @@ StatusCode RunAllen::initialize() error() << "Failed to obtain names_of_active_lines from gather_selections " << endmsg; return StatusCode::FAILURE; } - boost::split(m_line_names, selection_names->second, boost::is_any_of(",")); + boost::split(m_line_names, selection_names->second.get<std::string>(), boost::is_any_of(",")); if (m_line_names.empty()) { - error() << "Failed to obtain any line names from " << selection_names->second << endmsg; + error() << "Failed to obtain any line names from " << selection_names->second.get<std::string>() << endmsg; return StatusCode::FAILURE; } else { diff --git a/configuration/AllenCore/AllenSequenceGenerator.py b/configuration/AllenCore/AllenSequenceGenerator.py index 71ae4b9d0ebe4407b21cd0d334bb7350eadd267f..5450a6f2a59d6e9aeafd0196864b72cfb92f95f8 100644 --- a/configuration/AllenCore/AllenSequenceGenerator.py +++ b/configuration/AllenCore/AllenSequenceGenerator.py @@ -31,7 +31,7 @@ def generate_json_configuration(algorithms, filename): if len(algorithm.properties): sequence_json[algorithm.name] = {} for k, v in algorithm.properties.items(): - sequence_json[algorithm.name][str(k)] = str(v) + sequence_json[algorithm.name][str(k)] = v # Generate list of configured algorithms configured_algorithms = [[f"{algorithm.type.namespace()}::{algorithm.typename}", algorithm.name] for algorithm in algorithms] diff --git a/configuration/python/AllenConf/HLT1.py b/configuration/python/AllenConf/HLT1.py index defe3252e341a0e4ca70c5012ee976cebb60b96b..0225d71825f5557b36aa0d84924be8c66c385db7 100644 --- a/configuration/python/AllenConf/HLT1.py +++ b/configuration/python/AllenConf/HLT1.py @@ -81,12 +81,12 @@ def default_physics_lines(velo_tracks, forward_tracks, kalman_velo_only, name="Hlt1DiMuonLowMass", pre_scaler_hash_string="di_muon_low_mass_line_pre", post_scaler_hash_string="di_muon_low_mass_line_post", - minHighMassTrackPt="500.", - minHighMassTrackP="3000.", - minMass="0.", - maxDoca="0.2", - maxVertexChi2="25.", - minIPChi2="4."))) + minHighMassTrackPt=500., + minHighMassTrackP=3000., + minMass=0., + maxDoca=0.2, + maxVertexChi2=25., + minIPChi2=4.))) lines.append( line_maker("Hlt1DiMuonSoft", make_di_muon_soft_line(forward_tracks, secondary_vertices))) @@ -138,7 +138,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1NoBeam", make_beam_line( - beam_crossing_type="0", + beam_crossing_type=0, pre_scaler_hash_string="no_beam_line_pre", post_scaler_hash_string="no_beam_line_post"), enableGEC=False)) @@ -146,7 +146,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1BeamOne", make_beam_line( - beam_crossing_type="1", + beam_crossing_type=1, pre_scaler_hash_string="beam_one_line_pre", post_scaler_hash_string="beam_one_line_post"), enableGEC=False)) @@ -154,7 +154,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1BeamTwo", make_beam_line( - beam_crossing_type="2", + beam_crossing_type=2, pre_scaler_hash_string="beam_two_line_pre", post_scaler_hash_string="beam_two_line_post"), enableGEC=False)) @@ -162,7 +162,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1BothBeams", make_beam_line( - beam_crossing_type="3", + beam_crossing_type=3, pre_scaler_hash_string="both_beams_line_pre", post_scaler_hash_string="both_beams_line_post"), enableGEC=False)) @@ -175,7 +175,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1ODINLumi", make_odin_event_type_line( - odin_event_type="0x8", + odin_event_type=0x8, pre_scaler_hash_string="odin_lumi_line_pre", post_scaler_hash_string="odin_lumi_line_post"), enableGEC=False)) @@ -183,7 +183,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1ODINNoBias", make_odin_event_type_line( - odin_event_type="0x4", + odin_event_type=0x4, pre_scaler_hash_string="odin_no_bias_pre", post_scaler_hash_string="odin_no_bias_post"), enableGEC=False)) diff --git a/configuration/python/AllenConf/HLT1_no_calo.py b/configuration/python/AllenConf/HLT1_no_calo.py index 9a202944d425b7e745bd887cacb1aafdb74fe0fe..4fc21c98b4b8dc05d6813956b22c0b8becc43a79 100644 --- a/configuration/python/AllenConf/HLT1_no_calo.py +++ b/configuration/python/AllenConf/HLT1_no_calo.py @@ -99,12 +99,12 @@ def default_physics_lines(forward_tracks, kalman_velo_only, name="Hlt1DiMuonLowMass", pre_scaler_hash_string="di_muon_low_mass_line_pre", post_scaler_hash_string="di_muon_low_mass_line_post", - minHighMassTrackPt="500.", - minHighMassTrackP="3000.", - minMass="0.", - maxDoca="0.2", - maxVertexChi2="25.", - minIPChi2="4."), + minHighMassTrackPt=500., + minHighMassTrackP=3000., + minMass=0., + maxDoca=0.2, + maxVertexChi2=25., + minIPChi2=4.), enableGEC=True)) lines.append( line_maker( @@ -139,7 +139,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1NoBeam", make_beam_line( - beam_crossing_type="0", + beam_crossing_type=0, pre_scaler_hash_string="no_beam_line_pre", post_scaler_hash_string="no_beam_line_post"), enableGEC=False)) @@ -147,7 +147,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1BeamOne", make_beam_line( - beam_crossing_type="1", + beam_crossing_type=1, pre_scaler_hash_string="beam_one_line_pre", post_scaler_hash_string="beam_one_line_post"), enableGEC=False)) @@ -155,7 +155,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1BeamTwo", make_beam_line( - beam_crossing_type="2", + beam_crossing_type=2, pre_scaler_hash_string="beam_two_line_pre", post_scaler_hash_string="beam_two_line_post"), enableGEC=False)) @@ -163,7 +163,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1BothBeams", make_beam_line( - beam_crossing_type="3", + beam_crossing_type=3, pre_scaler_hash_string="both_beams_line_pre", post_scaler_hash_string="both_beams_line_post"), enableGEC=False)) @@ -176,7 +176,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1ODINLumi", make_odin_event_type_line( - odin_event_type="0x8", + odin_event_type=0x8, pre_scaler_hash_string="odin_lumi_line_pre", post_scaler_hash_string="odin_lumi_line_post"), enableGEC=False)) @@ -184,7 +184,7 @@ def default_monitoring_lines(velo_tracks): line_maker( "Hlt1ODINNoBias", make_odin_event_type_line( - odin_event_type="0x4", + odin_event_type=0x4, pre_scaler_hash_string="odin_no_bias_pre", post_scaler_hash_string="odin_no_bias_post"), enableGEC=False)) diff --git a/configuration/python/AllenConf/hlt1_monitoring_lines.py b/configuration/python/AllenConf/hlt1_monitoring_lines.py index bf713b080fae128ad28927762a1e8d3a98e4b562..900c5f67bde958d68d1afb0a7e3f461f0e9fea46 100644 --- a/configuration/python/AllenConf/hlt1_monitoring_lines.py +++ b/configuration/python/AllenConf/hlt1_monitoring_lines.py @@ -10,12 +10,12 @@ from AllenCore.generator import make_algorithm def make_beam_line(pre_scaler_hash_string="beam_line_pre", post_scaler_hash_string="beam_line_post", - beam_crossing_type="0"): + beam_crossing_type=0): name_map = { - "0": "Hlt1NoBeam", - "1": "Hlt1BeamOne", - "2": "Hlt1BeamTwo", - "3": "Hlt1BothBeams", + 0: "Hlt1NoBeam", + 1: "Hlt1BeamOne", + 2: "Hlt1BeamTwo", + 3: "Hlt1BothBeams", } number_of_events = initialize_number_of_events() odin = decode_odin() @@ -59,17 +59,16 @@ def make_velo_micro_bias_line( def make_odin_event_type_line( pre_scaler_hash_string="odin_event_type_line_pre", post_scaler_hash_string="odin_event_type_line_post", - odin_event_type="0x8"): + odin_event_type=0x8): name_map = {0x8: "Hlt1ODINLumi", 0x4: "Hlt1ODINNoBias"} number_of_events = initialize_number_of_events() odin = decode_odin() layout = mep_layout() - odin_event_type_int = int(odin_event_type, 0) return make_algorithm( odin_event_type_line_t, - name=name_map[odin_event_type_int], - odin_event_type=odin_event_type_int, + name=name_map[odin_event_type], + odin_event_type=odin_event_type, host_number_of_events_t=number_of_events["host_number_of_events"], dev_odin_raw_input_t=odin["dev_odin_raw_input"], dev_odin_raw_input_offsets_t=odin["dev_odin_raw_input_offsets"], diff --git a/configuration/python/AllenConf/hlt1_muon_lines.py b/configuration/python/AllenConf/hlt1_muon_lines.py index 9a184ec2f4774b9a49ce311666c48490217beb94..48d045f7ea99d80615cf5a4c0d8858100545749e 100644 --- a/configuration/python/AllenConf/hlt1_muon_lines.py +++ b/configuration/python/AllenConf/hlt1_muon_lines.py @@ -60,12 +60,12 @@ def make_di_muon_mass_line(forward_tracks, secondary_vertices, pre_scaler_hash_string="di_muon_mass_line_pre", post_scaler_hash_string="di_muon_mass_line_post", - minHighMassTrackPt="300.", - minHighMassTrackP="6000.", - minMass="2700.", - maxDoca="0.2", - maxVertexChi2="25.", - minIPChi2="0.", + minHighMassTrackPt=300., + minHighMassTrackP=6000., + minMass=2700., + maxDoca=0.2, + maxVertexChi2=25., + minIPChi2=0., name="Hlt1DiMuonHighMass"): number_of_events = initialize_number_of_events() odin = decode_odin() diff --git a/configuration/python/AllenConf/persistency.py b/configuration/python/AllenConf/persistency.py index db3fc31643b468ded637ec44ebd63b5781c6ff5e..e2bf4f887de7eb993eb0c81f82a469304c4fa863 100644 --- a/configuration/python/AllenConf/persistency.py +++ b/configuration/python/AllenConf/persistency.py @@ -41,7 +41,7 @@ def make_gather_selections(lines): @configurable -def make_dec_reporter(lines, TCK="0"): +def make_dec_reporter(lines, TCK=0): gather_selections = make_gather_selections(lines) number_of_events = initialize_number_of_events() diff --git a/configuration/python/AllenConf/scifi_reconstruction.py b/configuration/python/AllenConf/scifi_reconstruction.py index 67ea6de8d9adad9ecf5f621bb5932550dce13bc8..c308f303754e0b6a8e86fe9715a522a5724b5935 100644 --- a/configuration/python/AllenConf/scifi_reconstruction.py +++ b/configuration/python/AllenConf/scifi_reconstruction.py @@ -62,7 +62,7 @@ def decode_scifi(): @configurable -def make_forward_tracks(decoded_scifi, ut_tracks, hit_window_size="32"): +def make_forward_tracks(decoded_scifi, ut_tracks, hit_window_size=32): number_of_events = initialize_number_of_events() velo_tracks = ut_tracks["velo_tracks"] diff --git a/configuration/python/AllenConf/ut_reconstruction.py b/configuration/python/AllenConf/ut_reconstruction.py index ac971afc1a0b1532ecdf5ab252a93e79115e24ea..ac47ac5d6c4155d8e03e517d699b07a8e704a25c 100644 --- a/configuration/python/AllenConf/ut_reconstruction.py +++ b/configuration/python/AllenConf/ut_reconstruction.py @@ -100,18 +100,18 @@ def make_ut_tracks(decoded_ut, velo_tracks, restricted=True): "dev_velo_kalman_beamline_states_view"], dev_accepted_velo_tracks_t=dev_accepted_velo_tracks_t) - ut_search_windows_min_momentum = "1250.0" - ut_search_windows_min_pt = "275.0" - compass_ut_max_considered_before_found = "6" - compass_ut_min_momentum_final = "1500.0" - compass_ut_min_pt_final = "400.0" + ut_search_windows_min_momentum = 1250.0 + ut_search_windows_min_pt = 275.0 + compass_ut_max_considered_before_found = 6 + compass_ut_min_momentum_final = 1500.0 + compass_ut_min_pt_final = 400.0 if not restricted: - ut_search_windows_min_momentum = "1250.0" - ut_search_windows_min_pt = "200.0" - compass_ut_max_considered_before_found = "6" - compass_ut_min_momentum_final = "1500.0" - compass_ut_min_pt_final = "250.0" + ut_search_windows_min_momentum = 1250.0 + ut_search_windows_min_pt = 200.0 + compass_ut_max_considered_before_found = 6 + compass_ut_min_momentum_final = 1500.0 + compass_ut_min_pt_final = 250.0 ut_search_windows = make_algorithm( ut_search_windows_t, diff --git a/configuration/python/AllenConf/utils.py b/configuration/python/AllenConf/utils.py index 8bbc1a3e2fb61a1e3b1ed9cacff63a581e09ad42..26eedea7094c69ec0aa951654796fc7898f80855 100644 --- a/configuration/python/AllenConf/utils.py +++ b/configuration/python/AllenConf/utils.py @@ -18,7 +18,7 @@ def initialize_number_of_events(): } -def gec(name="gec", min_scifi_ut_clusters="0", max_scifi_ut_clusters="9750"): +def gec(name="gec", min_scifi_ut_clusters=0, max_scifi_ut_clusters=9750): number_of_events = initialize_number_of_events() host_ut_banks = make_algorithm( diff --git a/configuration/python/AllenConf/velo_reconstruction.py b/configuration/python/AllenConf/velo_reconstruction.py index b06bb4143c8c75c242fc66b45c52df0b9de18609..9c5f1f28a2e7afa35f7d47b60c50a4661b03e330 100644 --- a/configuration/python/AllenConf/velo_reconstruction.py +++ b/configuration/python/AllenConf/velo_reconstruction.py @@ -166,6 +166,7 @@ def make_velo_tracks(decoded_velo): dev_module_cluster_num_t=dev_module_cluster_num, dev_number_of_events_t=number_of_events["dev_number_of_events"], dev_velo_clusters_t=dev_velo_clusters, + max_skipped_modules=1, ) prefix_sum_offsets_velo_tracks = make_algorithm( diff --git a/main/include/BankTypes.h b/main/include/BankTypes.h index 760e8216689debaf3aaeb825c7927e8ef6d2883e..20cbe08405f6826d790508cc6a01be4e8f92b339 100644 --- a/main/include/BankTypes.h +++ b/main/include/BankTypes.h @@ -11,6 +11,8 @@ #include <vector> #include <cassert> #include <gsl/span> +#include "nlohmann/json.hpp" +#include "Common.h" constexpr auto NBankTypes = 11; enum class BankTypes { VP, VPRetinaCluster, UT, FT, MUON, ODIN, OTRaw, OTError, Rich, ECal, HCal, Unknown }; @@ -65,4 +67,9 @@ std::unordered_set<BankTypes> banks_set() return std::unordered_set<BankTypes> {BANKS...}; } +// Conversion functions from and to json +void from_json(const nlohmann::json& j, BankTypes& b); + +void to_json(nlohmann::json& j, const BankTypes& b); + #endif diff --git a/main/include/InputReader.h b/main/include/InputReader.h index f3fc5199de0cae0b6dc8ab8d5cf3832904fa9e3e..cab5ba0403eb8a8ba6c08521c661b1350a072ed1 100644 --- a/main/include/InputReader.h +++ b/main/include/InputReader.h @@ -154,19 +154,22 @@ private: struct ConfigurationReader { ConfigurationReader(const std::string& file_name); - ConfigurationReader(const std::map<std::string, std::map<std::string, std::string>>& params) : m_params(params) {} + ConfigurationReader(const std::map<std::string, std::map<std::string, nlohmann::json>>& params) : m_params(params) {} - std::map<std::string, std::string> params(std::string key) const + std::map<std::string, nlohmann::json> params(std::string key) const { - return (m_params.count(key) > 0 ? m_params.at(key) : std::map<std::string, std::string>()); + return (m_params.count(key) > 0 ? m_params.at(key) : std::map<std::string, nlohmann::json>()); } - std::map<std::string, std::map<std::string, std::string>> params() const { return m_params; } + std::map<std::string, std::map<std::string, nlohmann::json>> params() const { return m_params; } ConfiguredSequence configured_sequence() const { return m_configured_sequence; } void save(std::string file_name); + std::map<std::string, nlohmann::json> get_sequence() const; + private: - std::map<std::string, std::map<std::string, std::string>> m_params; + std::map<std::string, std::map<std::string, nlohmann::json>> m_params; + std::map<std::string, nlohmann::json> m_sequence; ConfiguredSequence m_configured_sequence; }; diff --git a/main/src/Allen.cpp b/main/src/Allen.cpp index d7cc810980266de246fa5294c9e39f3e352cab38..eb1a149f6812126349148bfe7323984ca773a137 100644 --- a/main/src/Allen.cpp +++ b/main/src/Allen.cpp @@ -330,10 +330,10 @@ int allen( // TODO: Test this if (print_config || write_config) { - auto algo_config = streams.front()->get_algorithm_configuration(); + auto algorithm_configuration = streams.front()->get_algorithm_configuration(); if (print_config) { info_cout << "Algorithm configuration\n"; - for (auto kv : algo_config) { + for (auto kv : algorithm_configuration) { for (auto kv2 : kv.second) { info_cout << " " << kv.first << ":" << kv2.first << " = " << kv2.second << "\n"; } @@ -341,7 +341,9 @@ int allen( } if (write_config) { info_cout << "Write full configuration\n"; - ConfigurationReader saveToJson(algo_config); + // Add sequence - this makes the generated json fully operational + algorithm_configuration["sequence"] = configuration_reader->get_sequence(); + ConfigurationReader saveToJson(algorithm_configuration); saveToJson.save("config.json"); return 0; } diff --git a/main/src/BankTypes.cpp b/main/src/BankTypes.cpp index 668e918da9633dc30bb54c43c073175069bd81f7..ef33a160ca327f504d3bea8e243665e1ea4cdd00 100644 --- a/main/src/BankTypes.cpp +++ b/main/src/BankTypes.cpp @@ -43,3 +43,14 @@ BankTypes bank_type(std::string bank_name) return BankTypes::Unknown; } } + +void from_json(const nlohmann::json& j, BankTypes& b) +{ + std::string s = j.get<std::string>(); + b = bank_type(s); + if (b == BankTypes::Unknown) { + throw StrException {"Failed to parse BankType " + s + "."}; + } +} + +void to_json(nlohmann::json& j, const BankTypes& b) { j = bank_name(b); } diff --git a/main/src/InputReader.cpp b/main/src/InputReader.cpp index b84af27f4cbfcdc258126d8283f2c1d24c152a81..5830cbc0d85d600137659fffb1d06bfadb5d6af5 100644 --- a/main/src/InputReader.cpp +++ b/main/src/InputReader.cpp @@ -186,21 +186,26 @@ ConfigurationReader::ConfigurationReader(const std::string& file_name) for (auto& el : j.items()) { std::string component = el.key(); if (component == "sequence") { + m_sequence = {}; for (auto& el2 : el.value().items()) { if (el2.key() == "configured_algorithms") { + m_sequence[el2.key()] = el2.value(); m_configured_sequence.configured_algorithms = ParsedSequence::to_configured<ConfiguredAlgorithm>( el2.value().get<ParsedSequence::configured_algorithm_parse_t>()); } else if (el2.key() == "configured_arguments") { + m_sequence[el2.key()] = el2.value(); m_configured_sequence.configured_arguments = ParsedSequence::to_configured<ConfiguredArgument>( el2.value().get<ParsedSequence::configured_argument_parse_t>()); } else if (el2.key() == "configured_sequence_arguments") { + m_sequence[el2.key()] = el2.value(); m_configured_sequence.configured_algorithm_arguments = ParsedSequence::to_configured<ConfiguredAlgorithmArguments>( el2.value().get<ParsedSequence::configured_algorithm_argument_parse_t>()); } else if (el2.key() == "argument_dependencies") { + m_sequence[el2.key()] = el2.value(); m_configured_sequence.argument_dependencies = el2.value().get<ParsedSequence::argument_dependencies_parse_t>(); } @@ -209,13 +214,7 @@ ConfigurationReader::ConfigurationReader(const std::string& file_name) else { for (auto& el2 : el.value().items()) { std::string property = el2.key(); - std::string value = ""; - if (el2.value().is_string()) { - value = el2.value().get<std::string>(); - } - else - throw StrException("Configuration JSON file " + file_name + " contains non-string parameter values."); - m_params[component][property] = value; + m_params[component][property] = el2.value(); } } } @@ -229,10 +228,12 @@ ConfigurationReader::ConfigurationReader(const std::string& file_name) } } +std::map<std::string, nlohmann::json> ConfigurationReader::get_sequence() const { return m_sequence; } + void ConfigurationReader::save(std::string file_name) { nlohmann::json j(m_params); std::ofstream o(file_name); - o << std::setw(4) << j; + o << j.dump(4); o.close(); } diff --git a/stream/gear/include/Algorithm.cuh b/stream/gear/include/Algorithm.cuh index fc425cddd408bc58f78b2077629e4df2f9854b43..ce12d82bd784ce991c57b5734c8f19b85f82ab8c 100644 --- a/stream/gear/include/Algorithm.cuh +++ b/stream/gear/include/Algorithm.cuh @@ -12,6 +12,7 @@ #include "RuntimeOptions.h" #include "Constants.cuh" #include "HostBuffers.cuh" +#include "nlohmann/json.hpp" #include <any> namespace { @@ -86,8 +87,8 @@ namespace Allen { *invoke)(void const*, std::any&, const RuntimeOptions&, const Constants&, HostBuffers&, const Allen::Context&) = nullptr; void (*init)(void*) = nullptr; - void (*set_properties)(void*, const std::map<std::string, std::string>&) = nullptr; - std::map<std::string, std::string> (*get_properties)(void const*) = nullptr; + void (*set_properties)(void*, const std::map<std::string, nlohmann::json>&) = nullptr; + std::map<std::string, nlohmann::json> (*get_properties)(void const*) = nullptr; std::string (*scope)() = nullptr; void (*dtor)(void*) = nullptr; void (*run_preconditions)( @@ -160,7 +161,7 @@ namespace Allen { _unused(p); } }, - [](void* p, const std::map<std::string, std::string>& algo_config) { + [](void* p, const std::map<std::string, nlohmann::json>& algo_config) { static_cast<ALGORITHM*>(p)->set_properties(algo_config); }, [](void const* p) { return static_cast<ALGORITHM const*>(p)->get_properties(); }, @@ -245,11 +246,11 @@ namespace Allen { (table.invoke)(instance, arg_ref_manager, runtime_options, constants, host_buffers, context); } void init() { (table.init)(instance); } - void set_properties(const std::map<std::string, std::string>& algo_config) + void set_properties(const std::map<std::string, nlohmann::json>& algo_config) { (table.set_properties)(instance, algo_config); } - std::map<std::string, std::string> get_properties() const { return (table.get_properties)(instance); } + std::map<std::string, nlohmann::json> get_properties() const { return (table.get_properties)(instance); } std::string scope() const { return (table.scope)(); } void run_preconditions( std::any& arg_ref_manager, @@ -307,7 +308,7 @@ namespace Allen { Algorithm(Algorithm&&) = delete; Algorithm& operator=(Algorithm&&) = delete; - void set_properties(const std::map<std::string, std::string>& algo_config) override + void set_properties(const std::map<std::string, nlohmann::json>& algo_config) override { for (auto kv : algo_config) { auto it = m_properties.find(kv.first); @@ -318,7 +319,12 @@ namespace Allen { throw std::runtime_error {error_message}; } else { - it->second->from_string(kv.second); + try { + it->second->from_json(kv.second); + } catch (nlohmann::detail::type_error& e) { + std::cerr << "json type error processing property " << kv.first << " of algorithm " << name() << "\n"; + throw e; + } } } } @@ -344,11 +350,11 @@ namespace Allen { return prop->get_value(); } - std::map<std::string, std::string> get_properties() const override + std::map<std::string, nlohmann::json> get_properties() const override { - std::map<std::string, std::string> properties; + std::map<std::string, nlohmann::json> properties; for (const auto& kv : m_properties) { - properties.emplace(kv.first, kv.second->to_string()); + properties.emplace(kv.first, kv.second->to_json()); } return properties; } diff --git a/stream/gear/include/BaseTypes.cuh b/stream/gear/include/BaseTypes.cuh index 28a327230434fd38acf7e1cdd090c0c45921038b..e3981447b18182df70d4e4fe9ef17a9e15d7f3ee 100644 --- a/stream/gear/include/BaseTypes.cuh +++ b/stream/gear/include/BaseTypes.cuh @@ -5,6 +5,7 @@ #include <map> #include <string> +#include "nlohmann/json.hpp" namespace Allen { /** @@ -14,7 +15,9 @@ namespace Allen { */ class BaseProperty { public: - virtual bool from_string(const std::string& value) = 0; + virtual void from_json(const nlohmann::json& value) = 0; + + virtual nlohmann::json to_json() const = 0; virtual std::string to_string() const = 0; @@ -28,9 +31,9 @@ namespace Allen { * */ struct BaseAlgorithm { - virtual void set_properties(const std::map<std::string, std::string>& algo_config) = 0; + virtual void set_properties(const std::map<std::string, nlohmann::json>& algo_config) = 0; - virtual std::map<std::string, std::string> get_properties() const = 0; + virtual std::map<std::string, nlohmann::json> get_properties() const = 0; virtual bool register_property(const std::string& name, BaseProperty* property) = 0; diff --git a/stream/gear/include/Property.cuh b/stream/gear/include/Property.cuh index 9bf04923fc33df29487ec3733e90d65ed6a394b7..b68cdc7d4add41a33b0cdb954329fbdd5146442f 100644 --- a/stream/gear/include/Property.cuh +++ b/stream/gear/include/Property.cuh @@ -19,123 +19,6 @@ #include <iostream> namespace Allen { - namespace Configuration { - namespace Detail { - std::regex const array_expr {"\\[(?:\\s*(\\d+)\\s*,?)+\\]"}; - std::regex const digit_expr {"(\\d+)"}; - } // namespace Detail - - template<typename T> - struct ConvertorFromString { - static auto convert(const std::string& s) - { - if constexpr (std::is_same_v<T, std::string>) { - return s; - } - else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>) { - return atof(s.c_str()); - } - else if constexpr (std::is_same_v<T, int8_t> || std::is_same_v<T, int16_t> || std::is_same_v<T, int32_t>) { - return strtol(s.c_str(), 0, 0); - } - else if constexpr (std::is_same_v<T, int64_t>) { - return strtoll(s.c_str(), 0, 0); - } - else if constexpr (std::is_same_v<T, uint8_t> || std::is_same_v<T, uint16_t> || std::is_same_v<T, uint32_t>) { - return strtoul(s.c_str(), 0, 0); - } - else if constexpr (std::is_same_v<T, uint64_t>) { - return strtoull(s.c_str(), 0, 0); - } - if constexpr (std::is_same_v<T, bool>) { - return atoi(s.c_str()); - } - if constexpr (std::is_same_v<T, char>) { - return s.at(0); - } - else if constexpr (std::is_same_v<T, BankTypes>) { - auto bt = bank_type(s); - if (bt == BankTypes::Unknown) { - throw StrException {"Failed to parse " + s + " into a BankType."}; - } - return bt; - } - else { - throw StrException {"ConvertorFromString instantiated with unsupported type."}; - } - } - }; - - template<typename T, std::size_t N> - struct ConvertorFromString<std::array<T, N>> { - static std::array<T, N> convert(const std::string& s) - { - std::array<T, N> output; - std::smatch matches; - auto r = std::regex_match(s, matches, Detail::array_expr); - if (!r) { - throw std::exception {}; - } - auto digits_begin = std::sregex_iterator(s.begin(), s.end(), Detail::digit_expr); - auto digits_end = std::sregex_iterator(); - if (std::distance(digits_begin, digits_end) != N) { - throw StrException {"Failed to parse from string, array size mismatch."}; - } - auto i = digits_begin; - for (std::size_t idx = 0; idx < N; ++idx, ++i) { - output[idx] = ConvertorFromString<T>::convert(i->str()); - } - return output; - } - }; - - template<typename T> - struct ConvertorToString { - static std::string convert(const T& holder) - { - if constexpr (std::is_same_v<T, BankTypes>) { - return bank_name(holder); - } - else { - std::stringstream s; - s << holder; - return s.str(); - } - } - }; - - template<typename T, std::size_t N> - struct ConvertorToString<std::array<T, N>> { - static std::string convert(const std::array<T, N> holder) - { - std::stringstream s; - s << "["; - for (size_t i = 0; i < N; ++i) { - s << holder[i]; - if (i != N - 1) { - s << ", "; - } - } - s << "]"; - return s.str(); - } - }; - - // General template - template<typename T> - bool from_string(T& holder, const std::string& value) - { - try { - holder = ConvertorFromString<typename T::t>::convert(value); - } catch (const std::exception&) { - std::cerr << "Could not parse JSON string from value \"" << value << "\"\n"; - return false; - } - - return true; - } - } // namespace Configuration - /** * @brief Store and readout the value of a single configurable algorithm property * @@ -155,17 +38,14 @@ namespace Allen { V get_value() const { return m_cached_value; } - virtual bool from_string(const std::string& value) override - { - V holder; - if (!Configuration::from_string<V>(holder, value)) return false; - set_value(holder); - return true; - } + void from_json(const nlohmann::json& value) override { set_value(value); } + + nlohmann::json to_json() const override { return m_cached_value.get(); } std::string to_string() const override { - return Configuration::ConvertorToString<typename V::t>::convert(m_cached_value.get()); + nlohmann::json j = m_cached_value.get(); + return j.dump(); } std::string print() const override @@ -176,7 +56,7 @@ namespace Allen { return s.str(); } - void set_value(V value) { m_cached_value = value; } + void set_value(typename V::t value) { m_cached_value = V {value}; } private: BaseAlgorithm* m_algo = nullptr; diff --git a/stream/gear/include/Scheduler.cuh b/stream/gear/include/Scheduler.cuh index 1660cb540240b1ea724aee24fe5ed064074a7499..d5d86f8eb7a471194e20686387d306c26b2b7143 100644 --- a/stream/gear/include/Scheduler.cuh +++ b/stream/gear/include/Scheduler.cuh @@ -10,6 +10,7 @@ #include <utility> #include <type_traits> #include <AlgorithmDB.h> +#include "nlohmann/json.hpp" // use constexpr flag to enable/disable contracts #ifdef ENABLE_CONTRACTS @@ -140,7 +141,7 @@ public: } // Configure constants for algorithms in the sequence - void configure_algorithms(const std::map<std::string, std::map<std::string, std::string>>& config) + void configure_algorithms(const std::map<std::string, std::map<std::string, nlohmann::json>>& config) { for (unsigned i = 0; i < m_sequence.size(); ++i) { configure(m_sequence[i], config); @@ -150,7 +151,7 @@ public: // Return constants for algorithms in the sequence auto get_algorithm_configuration() const { - std::map<std::string, std::map<std::string, std::string>> config; + std::map<std::string, std::map<std::string, nlohmann::json>> config; for (unsigned i = 0; i < m_sequence.size(); ++i) { get_configuration(m_sequence[i], config); } @@ -203,7 +204,7 @@ public: private: static void configure( Allen::TypeErasedAlgorithm& algorithm, - const std::map<std::string, std::map<std::string, std::string>>& config) + const std::map<std::string, std::map<std::string, nlohmann::json>>& config) { auto c = config.find(algorithm.name()); if (c != config.end()) algorithm.set_properties(c->second); @@ -213,7 +214,7 @@ private: static void get_configuration( const Allen::TypeErasedAlgorithm& algorithm, - std::map<std::string, std::map<std::string, std::string>>& config) + std::map<std::string, std::map<std::string, nlohmann::json>>& config) { config.emplace(algorithm.name(), algorithm.get_properties()); } diff --git a/stream/sequence/include/Stream.h b/stream/sequence/include/Stream.h index ba1d09e7261b7e70a72b12a410b789276819f28f..f89026966698b3541fa7d4cf68c6ddc47c14e03c 100644 --- a/stream/sequence/include/Stream.h +++ b/stream/sequence/include/Stream.h @@ -20,6 +20,7 @@ #include "HostBuffersManager.cuh" #include "CheckerInvoker.h" #include "Configuration.cuh" +#include "nlohmann/json.hpp" struct HostBuffers; struct HostBuffersManager; @@ -58,11 +59,11 @@ public: Allen::error run(const unsigned buf_idx, RuntimeOptions const& runtime_options); - void configure_algorithms(const std::map<std::string, std::map<std::string, std::string>>& config); + void configure_algorithms(const std::map<std::string, std::map<std::string, nlohmann::json>>& config); void print_configured_sequence(); - std::map<std::string, std::map<std::string, std::string>> get_algorithm_configuration() const; + std::map<std::string, std::map<std::string, nlohmann::json>> get_algorithm_configuration() const; bool contains_validation_algorithms() const; }; diff --git a/stream/sequence/src/Stream.cpp b/stream/sequence/src/Stream.cpp index bc6f55accc64b20ecfc484075199cf132fa0ae92..8b209d57e1f00401adfad09b098a8230044cc986 100644 --- a/stream/sequence/src/Stream.cpp +++ b/stream/sequence/src/Stream.cpp @@ -93,12 +93,12 @@ Allen::error Stream::run(const unsigned buf_idx, const RuntimeOptions& runtime_o */ void Stream::print_configured_sequence() { scheduler->print_sequence(); } -void Stream::configure_algorithms(const std::map<std::string, std::map<std::string, std::string>>& config) +void Stream::configure_algorithms(const std::map<std::string, std::map<std::string, nlohmann::json>>& config) { scheduler->configure_algorithms(config); } -std::map<std::string, std::map<std::string, std::string>> Stream::get_algorithm_configuration() const +std::map<std::string, std::map<std::string, nlohmann::json>> Stream::get_algorithm_configuration() const { return scheduler->get_algorithm_configuration(); }