Commit 80522e54 authored by Bednárek David RNDr. Ph.D.'s avatar Bednárek David RNDr. Ph.D.
Browse files

gold check files

parent 421aae31
......@@ -2,5 +2,5 @@
target_include_directories(${TARGET_MACRO} PUBLIC ".")
target_include_directories(${TARGET_LEVEN} PUBLIC ".")
target_sources(${TARGET_MACRO} PUBLIC "fmwkng.hpp" "macroasgn.hpp" "macroasgn.cpp" "macromain.cpp" "macrogold.cpp")
target_sources(${TARGET_LEVEN} PUBLIC "fmwkng.hpp" "levenasgn.hpp" "levenmain.cpp" "levengold.cpp")
target_sources(${TARGET_MACRO} PUBLIC "fmwkng.hpp" "macroasgn.hpp" "macroasgn.cpp" "macromain.cpp" "macrogolddebug.cpp" "macrogold.cpp")
target_sources(${TARGET_LEVEN} PUBLIC "fmwkng.hpp" "levenasgn.hpp" "levenmain.cpp" "levengolddebug.cpp" "levengold.cpp" "levengoldbig.cpp")
......@@ -42,6 +42,8 @@ namespace fmwkng {
enum class element_sense { OPEN, CLOSE };
enum class element_relevance { CHECK, TIME, SIZE_ };
template< element_sense sense>
struct sense_traits;
......@@ -69,6 +71,7 @@ namespace fmwkng {
virtual element_ptr aggregate_init() const = 0;
virtual void aggregate_to(abstract_element* aggr) const = 0;
virtual element_sense sense() const = 0;
virtual bool relevant(element_relevance er) const = 0;
virtual bool equal(const abstract_element* bp) const = 0;
};
......@@ -140,14 +143,14 @@ namespace fmwkng {
}
}
}
void gold_comparison_text(std::ostream& os, element_list_view gold) const
void gold_comparison_text(std::ostream& os, element_list_view gold, element_relevance er) const
{
std::size_t s = 0;
auto git = gold.begin();
for (auto it = begin(); it != end(); ++it)
{
if ((*it)->sense() == element_sense::CLOSE)
if ((*it)->sense() == element_sense::CLOSE && (*it)->relevant(er))
{
if (s)
os << "\t";
......@@ -250,9 +253,9 @@ namespace fmwkng {
{
element_list_view(*this).data_text(os);
}
void gold_comparison_text(std::ostream& os, const element_list & gold) const
void gold_comparison_text(std::ostream& os, const element_list & gold, element_relevance er) const
{
element_list_view(*this).gold_comparison_text(os, element_list_view(gold));
element_list_view(*this).gold_comparison_text(os, element_list_view(gold), er);
}
void metadata_text(std::ostream& os) const
{
......@@ -523,6 +526,12 @@ namespace fmwkng {
~gold_data() noexcept = default;
void append(gold_data b)
{
dm.merge(b.dm);
assert(b.dm.empty());
}
const impl::element_list* find(const impl::element_list& key) const
{
auto it = dm.find(key);
......@@ -536,6 +545,76 @@ namespace fmwkng {
};
namespace impl {
#pragma region enum_range
template< typename enum_t = std::size_t>
class enum_iterator {
private:
using self_ = enum_iterator<enum_t>;
public:
using iterator_category = std::input_iterator_tag;
using value_type = enum_t;
using difference_type = int;
using pointer = const enum_t*;
using reference = const enum_t&;
enum_iterator()
{}
explicit enum_iterator(enum_t v)
: v_(std::move(v))
{}
self_& operator++()
{
v_ = enum_t((int)v_ + 1);
return *this;
}
self_ operator++(int)
{
auto old = *this;
operator++();
return old;
}
bool operator==(const self_& b) const
{
return v_ == b.v_;
}
bool operator!=(const self_& b) const
{
return v_ != b.v_;
}
reference operator*() const
{
return v_;
}
pointer operator->() const
{
return &v_;
}
private:
enum_t v_;
};
template< typename enum_t>
class enum_range {
public:
using iterator = enum_iterator< enum_t>;
enum_range()
: b_(enum_t(0)), e_(enum_t::SIZE_)
{}
enum_range(enum_t b, enum_t e)
: b_(std::move(b)), e_(std::move(e))
{}
iterator begin() const
{
return iterator(b_);
}
iterator end() const
{
return iterator(e_);
}
private:
enum_t b_;
enum_t e_;
};
#pragma endregion
using element_observer_vector = std::vector<element_observer>;
inline void print_node(const gold_data& gd,
......@@ -560,19 +639,36 @@ namespace fmwkng {
}
else
{
element_list key;
std::array< element_list, std::size_t(element_relevance::SIZE_)> key;
for (auto&& a : openers)
{
key.push_back(a->clone());
for (auto v : enum_range<element_relevance>())
{
if (a->relevant(v))
{
key[std::size_t(v)].push_back(a->clone());
}
}
}
for (auto&& a : rn.reduced_children)
{
if (a->sense() == element_sense::OPEN)
key.push_back(a->clone());
{
for (auto v : enum_range<element_relevance>())
{
if (a->relevant(v))
{
key[std::size_t(v)].push_back(a->clone());
}
}
}
}
auto gold_value = gd.find(key);
std::array< const element_list *, std::size_t(element_relevance::SIZE_)> gold_value;
for (auto v : enum_range<element_relevance>())
{
gold_value[std::size_t(v)] = gd.find(key[std::size_t(v)]);
}
#ifdef PRINT_META
for (auto&& a : openers)
{
......@@ -601,14 +697,20 @@ namespace fmwkng {
++s;
}
if (!!gold_value && gold_value->data_size())
for (auto v : enum_range<element_relevance>())
{
if (!!s)
std::cout << '\t';
rn.reduced_children.gold_comparison_text(std::cout, *gold_value);
if (!!gold_value[std::size_t(v)] && gold_value[std::size_t(v)]->data_size())
{
rn.reduced_children.gold_comparison_text(std::cout, *gold_value[std::size_t(v)], v);
}
else
{
std::cout << '?';
}
++s;
}
std::cout << std::endl;
}
}
......@@ -616,6 +718,7 @@ namespace fmwkng {
inline void print_node_code(std::ostream& os,
const reducer_node& rn,
std::size_t depth,
element_relevance er,
const element_observer_vector& openers = {},
const element_observer_vector& closers = {})
{
......@@ -629,7 +732,7 @@ namespace fmwkng {
c2.push_back(&**(rn.source_range.end() - 1));
for (auto&& a : rn.children)
{
print_node_code(os, a, depth - 1, o2, c2);
print_node_code(os, a, depth - 1, er, o2, c2);
}
}
}
......@@ -641,14 +744,17 @@ namespace fmwkng {
os << std::endl;
for (auto&& a : openers)
{
os << " ";
a->make_code(os);
os << ",";
os << std::endl;
if (a->relevant(er))
{
os << " ";
a->make_code(os);
os << ",";
os << std::endl;
}
}
for (auto&& a : rn.reduced_children)
{
if (a->sense() == element_sense::OPEN)
if (a->sense() == element_sense::OPEN && a->relevant(er))
{
os << " ";
a->make_code(os);
......@@ -662,7 +768,7 @@ namespace fmwkng {
os << std::endl;
for (auto&& a : rn.reduced_children)
{
if (a->sense() == element_sense::CLOSE)
if (a->sense() == element_sense::CLOSE && a->relevant(er))
{
os << " ";
a->make_code(os);
......@@ -725,7 +831,7 @@ namespace fmwkng {
print_all(gold_data(), el, prefix);
}
inline void print_all_code(std::ostream & os, element_list_view el)
inline void print_all_code(std::ostream & os, element_list_view el, element_relevance er)
{
auto root = reduce_list(el);
auto depth = deepest_reducible(root);
......@@ -734,7 +840,7 @@ namespace fmwkng {
--d;
for (auto&& a : root)
{
print_node_code(os, a, d);
print_node_code(os, a, d, er);
}
}
}
......@@ -780,6 +886,10 @@ namespace fmwkng {
{
return sense_p;
}
virtual bool relevant(element_relevance er) const override
{
return my_traits::relevant(er);
}
virtual bool useful() const override
{
return my_traits::useful;
......@@ -850,6 +960,10 @@ namespace fmwkng {
{
return sense_p;
}
virtual bool relevant(element_relevance er) const override
{
return false;
}
virtual bool useful() const override
{
return false;
......@@ -945,6 +1059,10 @@ namespace fmwkng {
{
return element_sense::OPEN;
}
virtual bool relevant(element_relevance er) const override
{
return my_traits::relevant(er);
}
virtual bool useful() const override
{
return false;
......@@ -1016,6 +1134,10 @@ namespace fmwkng {
{
return element_sense::CLOSE;
}
virtual bool relevant(element_relevance) const override
{
return false;
}
virtual bool useful() const override
{
return false;
......@@ -1081,6 +1203,10 @@ namespace fmwkng {
{
return element_sense::OPEN;
}
virtual bool relevant(element_relevance) const override
{
return false;
}
virtual bool useful() const override
{
return false;
......@@ -1155,6 +1281,10 @@ namespace fmwkng {
{
return element_sense::CLOSE;
}
virtual bool relevant(element_relevance er) const override
{
return my_traits::relevant(er);
}
virtual bool useful() const override
{
return false;
......@@ -1782,6 +1912,10 @@ namespace fmwkng {
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static bool relevant(element_relevance er)
{
return er == element_relevance::TIME;
}
template< element_sense sense>
using aggregator = element_t< root_tag< config_t>, sense>;
static data_type aggregator_data(const data_type& v)
......@@ -1864,25 +1998,28 @@ namespace fmwkng {
print_elements();
}
print_all_elements();
if (!code_fn_.empty())
for (int i = 0; i < int(element_relevance::SIZE_); ++i)
{
std::cout << "Generating C++ code into " << code_fn_ << std::endl;
std::ofstream os(code_fn_);
os << "#include \"fmwkng.hpp\"" << std::endl;
os << "#include \"" << config_t::code_header_name() << "\"" << std::endl;
os << "" << std::endl;
os << "namespace " << config_t::code_namespace_name() << " {" << std::endl;
os << " const fmwkng::gold_data & gold_results()" << std::endl;
os << " {" << std::endl;
os << " static fmwkng::gold_data gd_{" << std::endl;
print_all_code(os, all_el_);
os << " };" << std::endl;
os << " return gd_;" << std::endl;
os << " }" << std::endl;
os << "}" << std::endl;
if (!code_fn_[i].empty())
{
std::cout << "Generating C++ code into " << code_fn_[i] << std::endl;
std::ofstream os(code_fn_[i]);
os << "#include \"fmwkng.hpp\"" << std::endl;
os << "#include \"" << config_t::code_header_name() << "\"" << std::endl;
os << "" << std::endl;
os << "namespace " << config_t::code_namespace_name() << " {" << std::endl;
os << " static fmwkng::gold_data gold_results_()" << std::endl;
os << " {" << std::endl;
os << " return fmwkng::gold_data{" << std::endl;
print_all_code(os, all_el_, element_relevance(i));
os << " };" << std::endl;
os << " }" << std::endl;
os << " static fmwkng::gold_holder gh_(gold_master(), gold_results_);" << std::endl;
os << "}" << std::endl;
}
}
}
......@@ -1970,7 +2107,7 @@ namespace fmwkng {
mutable master master_;
mutable element_list el_;
mutable element_list all_el_;
std::string code_fn_;
std::array< std::string, std::size_t(element_relevance::SIZE_)> code_fn_;
gold_data gd_;
std::string machine_name_;
bool direct_print_;
......@@ -2044,9 +2181,13 @@ namespace fmwkng {
value = std::string_view(&*cite + 1, a.end() - cite - 1);
}
if (name == "code")
{
code_fn_ = value;
if (name == "code-check")
{
code_fn_[std::size_t(element_relevance::CHECK)] = value;
}
else if (name == "code-time")
{
code_fn_[std::size_t(element_relevance::TIME)] = value;
}
else if (name == "machine")
{
......@@ -2059,6 +2200,15 @@ namespace fmwkng {
else
direct_print_ = false;
}
else if (name == "platform")
{
config_t::platforms::for_each([this, value](auto rs) {
using platform_tag = pass_t<decltype(rs)>;
static constexpr auto index = config_t::platforms::template index_v<platform_tag>;
auto&& cfg = std::get<index>(platform_enablers_);
cfg = (value == platform_tag::name());
});
}
else
{
config_t::ranges::for_each([this, name, value](auto rs) {
......@@ -2170,6 +2320,10 @@ namespace fmwkng {
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static bool relevant(element_relevance er)
{
return er == element_relevance::TIME;
}
template< element_sense sense>
using aggregator = config_element< all_platforms_tag, sense>;
static data_type aggregator_data(const data_type&)
......@@ -2263,6 +2417,10 @@ namespace fmwkng {
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static bool relevant(element_relevance)
{
return true;
}
template< element_sense sense>
using aggregator = config_element< range_tag, sense>;
static aggregator_data_type aggregator_data(const data_type& v)
......@@ -2300,6 +2458,10 @@ namespace fmwkng {
{
os << ".";
}
static bool relevant(element_relevance er)
{
return true; // distinguish between a particular platform and the aggregate
}
using data_type = std::monostate;
static void data_text(std::ostream& os, const data_type& d)
{
......@@ -2336,6 +2498,10 @@ namespace fmwkng {
{
os << ".";
}
static bool relevant(element_relevance er)
{
return true; // distinguish from debug (no thread) mode
}
using data_type = std::monostate;
static void data_text(std::ostream& os, const data_type& d)
{
......@@ -2372,6 +2538,10 @@ namespace fmwkng {
{
os << ")";
}
static bool relevant(element_relevance er)
{
return true;
}
using data_type = typename range_config_holder< range_tag>::enumerator_t;
static void data_text(std::ostream& os, const data_type & d)
{
......@@ -2510,6 +2680,10 @@ namespace fmwkng {
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static bool relevant(element_relevance)
{
return true;
}
template< element_sense sense>
using aggregator = config_element< all_threads_tag, sense>;
using aggregate_data_type = std::monostate;
......@@ -2744,6 +2918,10 @@ namespace fmwkng {
}
static constexpr bool useful = true;
static constexpr bool reducible = true;
static bool relevant(element_relevance er)
{
return er == element_relevance::TIME;
}
using aggregator_data_type = std::pair< clock::duration, std::size_t>;
template< element_sense sense>
using aggregator = result_element< measurement_tag, sense>;
......@@ -2770,6 +2948,10 @@ namespace fmwkng {
{
os << ">";
}
static bool relevant(element_relevance er)
{
return er == element_relevance::TIME;
}
using data_type = std::pair< clock::duration, std::size_t>;
static void data_text(std::ostream& os, const data_type& d)
{
......@@ -2882,6 +3064,10 @@ namespace fmwkng {
}
static constexpr bool useful = true;
static constexpr bool reducible = true;
static bool relevant(element_relevance er)
{
return er == element_relevance::CHECK;
}
template< element_sense sense>
using aggregator = element_t< result_tag, sense>;
static data_type aggregator_data(const data_type& v)
......@@ -3065,6 +3251,10 @@ namespace fmwkng {
}
static constexpr bool useful = true;
static constexpr bool reducible = true;
static bool relevant(element_relevance er)
{
return er == element_relevance::TIME;
}
template< element_sense sense>
using aggregator = result_element< auto_measurement_tag< measurement_policy>, sense>;
using aggregator_data_type = std::pair< double, std::size_t>;
......@@ -3092,6 +3282,10 @@ namespace fmwkng {
{
os << measurement_policy::name() << "[ns]]";
}
static bool relevant(element_relevance er)
{
return er == element_relevance::TIME;
}
using data_type = std::pair< double, std::size_t>;
static void data_text(std::ostream& os, const data_type& d)
{
......@@ -3955,6 +4149,35 @@ namespace fmwkng {
return operator=(gold_data(b));
}
using gold_fnc_ptr = gold_data(*)();
class gold_holder : impl::immovable {
public:
gold_holder() // MASTER
: prev_(this), next_(this), fnc_(nullptr)
{}
gold_holder(gold_holder & master, gold_fnc_ptr fnc) // SLAVE
: prev_(master.prev_), next_(&master), fnc_(fnc)
{
prev_->next_ = this;
next_->prev_ = this;
}
gold_data collect() const
{
gold_data gd;
for (auto p = next_; p != this; p = p->next_)
{
assert(!!p->fnc_);
gd.append(p->fnc_());
}
return gd;
}
private:
gold_holder* prev_;
gold_holder* next_;
gold_fnc_ptr fnc_;
};
#pragma endregion
}
......
......@@ -156,13 +156,13 @@ namespace levenmain {
static auto code_name() { return "levenmain::a_size"; }
static auto enumerator() {
return fmwkng::logarithmic(
0x40,
0x80,
#ifdef NDEBUG
0x10000,
0x8000,
#else
0x1000,
0x800,
#endif
0x20
0x10
);
}
};
......@@ -173,13 +173,13 @@ namespace levenmain {
static auto code_name() { return "levenmain::b_size"; }
static auto enumerator() {
return fmwkng::logarithmic(
0x40,
0x80,
#ifdef NDEBUG
0x10000,
0x8000,
#else
0x1000,
0x800,
#endif
0x20
0x10
);
}
};
......@@ -208,7 +208,13 @@ namespace levenmain {
{
return (std::uint_fast64_t)fmwkng::get<a_size>(ctx) * fmwkng::get<b_size>(ctx);
}
static constexpr fmwkng::average_t minimum_count = 1000000000ULL;
static constexpr fmwkng::average_t minimum_count =
#ifdef NDEBUG
1000000000ULL