Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 9 additions & 34 deletions phlex/core/product_query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "phlex/model/product_specification.hpp"
#include "phlex/model/type_id.hpp"

#include <concepts>
#include <optional>
#include <string>
#include <tuple>
Expand All @@ -16,53 +17,27 @@ using namespace phlex::experimental::literals;
namespace phlex {
namespace detail {
template <typename T>
requires std::is_same_v<experimental::identifier,
T> // has to be a template for static_assert(false)
class required_creator_name {
class required {
public:
required_creator_name()
{
static_assert(false, "The creator name has not been set in this product_query.");
}
required_creator_name(T&& rhs) : content_(std::move(rhs))
{
if (content_.empty()) {
throw std::runtime_error("Cannot specify product with empty creator name.");
}
}

operator T const&() const noexcept { return content_; }

private:
experimental::identifier content_;
};

template <typename T>
requires std::is_same_v<experimental::identifier,
T> // has to be a template for static_assert(false)
class required_layer_name {
public:
required_layer_name()
{
static_assert(false, "The layer name has not been set in this product_query.");
}
required_layer_name(T&& rhs) : content_(std::move(rhs))
template <typename U>
requires std::constructible_from<T, U>
required(U&& u) : content_{std::forward_like<T>(u)}
{
if (content_.empty()) {
throw std::runtime_error("Cannot specify the empty string as a data layer.");
throw std::runtime_error("Cannot specify the empty string as a required field.");
}
}

operator T const&() const noexcept { return content_; }

private:
experimental::identifier content_;
T content_;
};
}

struct product_query {
detail::required_creator_name<experimental::identifier> creator;
detail::required_layer_name<experimental::identifier> layer;
detail::required<experimental::identifier> creator;
detail::required<experimental::identifier> layer;
std::optional<experimental::identifier> suffix;
std::optional<experimental::identifier> stage;
experimental::type_id type;
Expand Down
1 change: 1 addition & 0 deletions phlex/model/identifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace phlex::experimental {
return h.result();
}

identifier::identifier(char const* str) : identifier{std::string_view{str}} {}
identifier::identifier(std::string_view str) : content_(str), hash_(hash_string(content_)) {}

identifier::operator std::string_view() const noexcept { return std::string_view(content_); }
Expand Down
1 change: 1 addition & 0 deletions phlex/model/identifier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace phlex::experimental {
identifier(identifier const& other) = default;
identifier(identifier&& other) noexcept = default;

identifier(char const* str);
explicit identifier(std::string_view str);

identifier& operator=(identifier const& rhs) = default;
Expand Down
20 changes: 10 additions & 10 deletions test/allowed_families.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ TEST_CASE("Testing families", "[data model]")

// Wire up providers for each level
g.provide("run_id_provider", provide_index, concurrency::unlimited)
.output_product(product_query{.creator = "dummy"_id, .layer = "run"_id, .suffix = "id"_id});
.output_product(product_query{.creator = "dummy", .layer = "run", .suffix = "id"});
g.provide("subrun_id_provider", provide_index, concurrency::unlimited)
.output_product(product_query{.creator = "dummy"_id, .layer = "subrun"_id, .suffix = "id"_id});
.output_product(product_query{.creator = "dummy", .layer = "subrun", .suffix = "id"});
g.provide("event_id_provider", provide_index, concurrency::unlimited)
.output_product(product_query{.creator = "dummy"_id, .layer = "event"_id, .suffix = "id"_id});
.output_product(product_query{.creator = "dummy", .layer = "event", .suffix = "id"});

g.observe("se", check_two_ids)
.input_family(product_query{.creator = "dummy"_id, .layer = "subrun"_id, .suffix = "id"_id},
product_query{.creator = "dummy"_id, .layer = "event"_id, .suffix = "id"_id});
.input_family(product_query{.creator = "dummy", .layer = "subrun", .suffix = "id"},
product_query{.creator = "dummy", .layer = "event", .suffix = "id"});
g.observe("rs", check_two_ids)
.input_family(product_query{.creator = "dummy"_id, .layer = "run"_id, .suffix = "id"_id},
product_query{.creator = "dummy"_id, .layer = "subrun"_id, .suffix = "id"_id});
.input_family(product_query{.creator = "dummy", .layer = "run", .suffix = "id"},
product_query{.creator = "dummy", .layer = "subrun", .suffix = "id"});
g.observe("rse", check_three_ids)
.input_family(product_query{.creator = "dummy"_id, .layer = "run"_id, .suffix = "id"_id},
product_query{.creator = "dummy"_id, .layer = "subrun"_id, .suffix = "id"_id},
product_query{.creator = "dummy"_id, .layer = "event"_id, .suffix = "id"_id});
.input_family(product_query{.creator = "dummy", .layer = "run", .suffix = "id"},
product_query{.creator = "dummy", .layer = "subrun", .suffix = "id"},
product_query{.creator = "dummy", .layer = "event", .suffix = "id"});
g.execute();

CHECK(g.execution_count("se") == 1ull);
Expand Down
2 changes: 1 addition & 1 deletion test/benchmarks/benchmarks_provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ PHLEX_REGISTER_PROVIDERS(s)
{
using namespace phlex;
s.provide("provide_id", [](data_cell_index const& id) { return id; })
.output_product(product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "id"_id});
.output_product(product_query{.creator = "input", .layer = "event", .suffix = "id"});
}
2 changes: 1 addition & 1 deletion test/benchmarks/last_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ namespace {
PHLEX_REGISTER_ALGORITHMS(m, config)
{
m.transform("last_index", last_index, concurrency::unlimited)
.input_family(product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "id"_id})
.input_family(product_query{.creator = "input", .layer = "event", .suffix = "id"})
.output_products(config.get<std::string>("produces", "a"));
}
2 changes: 1 addition & 1 deletion test/benchmarks/read_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ namespace {
PHLEX_REGISTER_ALGORITHMS(m)
{
m.observe("read_id", read_id, concurrency::unlimited)
.input_family(product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "id"_id});
.input_family(product_query{.creator = "input", .layer = "event", .suffix = "id"});
}
27 changes: 12 additions & 15 deletions test/cached_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,37 +61,34 @@ TEST_CASE("Cached function calls", "[data model]")

// Register providers
g.provide("provide_number", provide_number, concurrency::unlimited)
.output_product(product_query{.creator = "input"_id, .layer = "run"_id, .suffix = "number"_id});
.output_product(product_query{.creator = "input", .layer = "run", .suffix = "number"});
g.provide("provide_another", provide_another, concurrency::unlimited)
.output_product(
product_query{.creator = "input"_id, .layer = "subrun"_id, .suffix = "another"_id});
.output_product(product_query{.creator = "input", .layer = "subrun", .suffix = "another"});
g.provide("provide_still", provide_still, concurrency::unlimited)
.output_product(
product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "still"_id});
.output_product(product_query{.creator = "input", .layer = "event", .suffix = "still"});

g.transform("A1", call_one, concurrency::unlimited)
.input_family(product_query{.creator = "input"_id, .layer = "run"_id, .suffix = "number"_id})
.input_family(product_query{.creator = "input", .layer = "run", .suffix = "number"})
.output_products("one");
g.transform("A2", call_one, concurrency::unlimited)
.input_family(product_query{.creator = "A1"_id, .layer = "run"_id, .suffix = "one"_id})
.input_family(product_query{.creator = "A1", .layer = "run", .suffix = "one"})
.output_products("used_one");
g.transform("A3", call_one, concurrency::unlimited)
.input_family(product_query{.creator = "A2"_id, .layer = "run"_id, .suffix = "used_one"_id})
.input_family(product_query{.creator = "A2", .layer = "run", .suffix = "used_one"})
.output_products("done_one");

g.transform("B1", call_two, concurrency::unlimited)
.input_family(
product_query{.creator = "A1"_id, .layer = "run"_id, .suffix = "one"_id},
product_query{.creator = "input"_id, .layer = "subrun"_id, .suffix = "another"_id})
.input_family(product_query{.creator = "A1", .layer = "run", .suffix = "one"},
product_query{.creator = "input", .layer = "subrun", .suffix = "another"})
.output_products("two");
g.transform("B2", call_two, concurrency::unlimited)
.input_family(product_query{.creator = "A2"_id, .layer = "run"_id, .suffix = "used_one"_id},
product_query{.creator = "B1"_id, .layer = "subrun"_id, .suffix = "two"_id})
.input_family(product_query{.creator = "A2", .layer = "run", .suffix = "used_one"},
product_query{.creator = "B1", .layer = "subrun", .suffix = "two"})
.output_products("used_two");

g.transform("C", call_two, concurrency::unlimited)
.input_family(product_query{.creator = "B2"_id, .layer = "subrun"_id, .suffix = "used_two"_id},
product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "still"_id})
.input_family(product_query{.creator = "B2", .layer = "subrun", .suffix = "used_two"},
product_query{.creator = "input", .layer = "event", .suffix = "still"})
.output_products("three");

g.execute();
Expand Down
13 changes: 6 additions & 7 deletions test/class_registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,20 @@ namespace {
TEST_CASE("Call non-framework functions", "[programming model]")
{
std::array const product_names{
product_query{.creator = "input"_id, .layer = "job"_id, .suffix = "number"_id},
product_query{.creator = "input"_id, .layer = "job"_id, .suffix = "temperature"_id},
product_query{.creator = "input"_id, .layer = "job"_id, .suffix = "name"_id}};
product_query{.creator = "input", .layer = "job", .suffix = "number"},
product_query{.creator = "input", .layer = "job", .suffix = "temperature"},
product_query{.creator = "input", .layer = "job", .suffix = "name"}};
std::array const oproduct_names{"onumber"s, "otemperature"s, "oname"s};

experimental::framework_graph g{data_cell_index::base_ptr()};

// Register providers for the input products
g.provide("provide_number", provide_number, concurrency::unlimited)
.output_product(product_query{.creator = "input"_id, .layer = "job"_id, .suffix = "number"_id});
.output_product(product_query{.creator = "input", .layer = "job", .suffix = "number"});
g.provide("provide_temperature", provide_temperature, concurrency::unlimited)
.output_product(
product_query{.creator = "input"_id, .layer = "job"_id, .suffix = "temperature"_id});
.output_product(product_query{.creator = "input", .layer = "job", .suffix = "temperature"});
g.provide("provide_name", provide_name, concurrency::unlimited)
.output_product(product_query{.creator = "input"_id, .layer = "job"_id, .suffix = "name"_id});
.output_product(product_query{.creator = "input", .layer = "job", .suffix = "name"});

auto glueball = g.make<A>();
SECTION("No framework")
Expand Down
4 changes: 2 additions & 2 deletions test/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ TEST_CASE("Retrieve product_query", "[config]")
configuration config{underlying_config};

auto input_query = config.get<product_query>("input");
CHECK(input_query.match(
product_query{.creator = "tracks_alg"_id, .layer = "job"_id, .suffix = "tracks"_id}));
CHECK(
input_query.match(product_query{.creator = "tracks_alg", .layer = "job", .suffix = "tracks"}));
CHECK_THROWS_WITH(config.get<product_query>("malformed1"),
ContainsSubstring("Error retrieving parameter 'malformed1'") &&
ContainsSubstring("not a string"));
Expand Down
11 changes: 5 additions & 6 deletions test/demo-giantdata/unfold_transform_fold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ TEST_CASE("Unfold-transform-fold pipeline", "[concurrency][unfold][fold]")
spill_index.parent()->number(),
spill_index.number());
})
.output_product(product_query{.creator = "input"_id, .layer = "spill"_id, .suffix = "wgen"_id});
.output_product(product_query{.creator = "input", .layer = "spill", .suffix = "wgen"});

g.unfold<demo::WaveformGenerator>(
"WaveformGenerator",
Expand All @@ -71,7 +71,7 @@ TEST_CASE("Unfold-transform-fold pipeline", "[concurrency][unfold][fold]")
},
concurrency::unlimited,
"APA")
.input_family(product_query{.creator = "input"_id, .layer = "spill"_id, .suffix = "wgen"_id})
.input_family(product_query{.creator = "input", .layer = "spill", .suffix = "wgen"})
.output_products("waves_in_apa");

// Add the transform node to the graph
Expand All @@ -80,8 +80,8 @@ TEST_CASE("Unfold-transform-fold pipeline", "[concurrency][unfold][fold]")
};

g.transform("clamp_node", wrapped_user_function, concurrency::unlimited)
.input_family(product_query{
.creator = "WaveformGenerator"_id, .layer = "APA"_id, .suffix = "waves_in_apa"_id})
.input_family(
product_query{.creator = "WaveformGenerator", .layer = "APA", .suffix = "waves_in_apa"})
.output_products("clamped_waves");

// Add the fold node with instrumentation to detect pipelined execution
Expand All @@ -98,8 +98,7 @@ TEST_CASE("Unfold-transform-fold pipeline", "[concurrency][unfold][fold]")
},
concurrency::unlimited,
"spill")
.input_family(
product_query{.creator = "clamp_node"_id, .layer = "APA"_id, .suffix = "clamped_waves"_id})
.input_family(product_query{.creator = "clamp_node", .layer = "APA", .suffix = "clamped_waves"})
.output_products("summed_waveforms");

// Execute the graph
Expand Down
13 changes: 5 additions & 8 deletions test/different_hierarchies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,22 @@ TEST_CASE("Different hierarchies used with fold", "[graph]")

// Register provider
g.provide("provide_number", provide_number, concurrency::unlimited)
.output_product(
product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "number"_id});
.output_product(product_query{.creator = "input", .layer = "event", .suffix = "number"});

g.fold("run_add", add, concurrency::unlimited, "run", 0u)
.input_family(product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "number"_id})
.input_family(product_query{.creator = "input", .layer = "event", .suffix = "number"})
.output_products("run_sum");
g.fold("job_add", add, concurrency::unlimited)
.input_family(product_query{.creator = "input"_id, .layer = "event"_id, .suffix = "number"_id})
.input_family(product_query{.creator = "input", .layer = "event", .suffix = "number"})
.output_products("job_sum");

g.observe("verify_run_sum", [](unsigned int actual) { CHECK(actual == 10u); })
.input_family(
product_query{.creator = "run_add"_id, .layer = "run"_id, .suffix = "run_sum"_id});
.input_family(product_query{.creator = "run_add", .layer = "run", .suffix = "run_sum"});
g.observe("verify_job_sum",
[](unsigned int actual) {
CHECK(actual == 20u + 45u); // 20u from nested events, 45u from top-level events
})
.input_family(
product_query{.creator = "job_add"_id, .layer = "job"_id, .suffix = "job_sum"_id});
.input_family(product_query{.creator = "job_add", .layer = "job", .suffix = "job_sum"});

g.execute();

Expand Down
Loading
Loading