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

complexity-aware auto_measurement

more extensive testing
parent 0854369b
......@@ -51,7 +51,7 @@ namespace fmwkng {
class element_list {
public:
void push_back(element_ptr && ep)
void push_back(element_ptr&& ep)
{
ev_.push_back(std::move(ep));
}
......@@ -504,6 +504,9 @@ namespace fmwkng {
context_t c_;
};
#pragma endregion
}
using average_t = std::uint_fast64_t;
namespace impl {
#pragma region parallel_utils
class master : impl::immovable {
public:
......@@ -563,8 +566,6 @@ namespace fmwkng {
ba_promise bap_;
};
using average_t = std::uint_fast64_t;
using master_worker_message = std::variant<std::monostate, std::monostate, average_t>;
struct master_worker_message_type {
static constexpr std::size_t STOP = 0;
......@@ -1559,6 +1560,11 @@ namespace fmwkng {
: v_first_(v_first), v_last_(v_last), v_factor_(v_factor)
{}
void set_arg(std::string_view s)
{
v_last_ = (value_type)std::stoull(std::string(s));
}
void set_v_last(std::size_t v_last)
{
v_last_ = v_last;
......@@ -1603,14 +1609,14 @@ namespace fmwkng {
#pragma endregion
namespace impl {
#pragma region auto_measurement
template< typename ... range_tags>
template< typename measurement_policy>
struct auto_measurement_tag {
using tag_category = measurement_tag_category;
static fmwkng::logarithmic<> enumerator() { return fmwkng::logarithmic<>(1, 16); }
};
template< typename ... range_tags>
struct element_traits< measurement_tag_category, auto_measurement_tag< range_tags...>, element_sense::OPEN>
template< typename measurement_policy>
struct element_traits< measurement_tag_category, auto_measurement_tag< measurement_policy>, element_sense::OPEN>
{
static void metadata_marker(std::ostream& os)
{
......@@ -1627,22 +1633,22 @@ namespace fmwkng {
*/
};
template< typename ... range_tags>
struct element_traits< measurement_tag_category, auto_measurement_tag< range_tags ...>, element_sense::CLOSE>
template< typename measurement_policy>
struct element_traits< measurement_tag_category, auto_measurement_tag< measurement_policy>, element_sense::CLOSE>
{
static void metadata_marker(std::ostream& os)
{
os << "ns]";
os << measurement_policy::name() << "[ns]]";
}
using data_type = clock::duration;
using data_type = double;
static void data_text(std::ostream& os, const data_type& d)
{
os << d.count();
os << d;
}
static constexpr bool useful = true;
};
template< typename ... range_tags>
template< typename measurement_policy>
class auto_measurement_data_holder {
public:
auto_measurement_data_holder(std::size_t v_last)
......@@ -1726,18 +1732,20 @@ namespace fmwkng {
time_point start_, stop_;
time_delta delta_;
average_t avg_delta_;
using my_tag = auto_measurement_tag< range_tags...>;
using my_tag = auto_measurement_tag< measurement_policy>;
range_config_holder<my_tag> rch_;
using value_type = enumerator_value_t<my_tag>;
value_type v_;
static constexpr average_t minimum_count = 1000000000UL;
using my_ranges = ranges< range_tags...>;
static constexpr average_t minimum_count = measurement_policy::minimum_count;
using my_ranges = typename measurement_policy::ranges;
typename my_ranges::tuple_t range_configs_;
std::uint_fast64_t count_sum_;
template< typename dt_t>
void reconfig(const dt_t& dt, std::size_t multiplier, std::size_t divisor)
{
auto root = impl::root_pointer(dt);
count_sum_ = 0;
my_ranges::for_each([this, root, multiplier, divisor](auto p) {
using range_tag = impl::pass_t<decltype(p)>;
using c_type = typename range_config_holder<range_tag>::enumerator_t;
......@@ -1745,6 +1753,8 @@ namespace fmwkng {
auto&& base_c = root->template get_range_config<range_tag>();
auto&& my_c = std::get<index>(range_configs_);
my_c.config = c_type(base_c.config, multiplier, divisor);
//std::cout << my_c.config.count() << " = " << base_c.config.count() << " * " << multiplier << " / " << divisor << std::endl;
count_sum_ += my_c.config.count();
});
}
......@@ -1777,7 +1787,7 @@ namespace fmwkng {
template< typename dt_t>
void enter_phase(const dt_t& dt)
{
reconfig(dt, v_, p_ == phase::TEST ? 1 : 5); // 20% lead-in/out
reconfig(dt, v_, (std::uint_fast64_t)complexity(dt) * (p_ == phase::TEST ? 1 : 5)); // 20% lead-in/out
{
/*
auto g = impl::root_pointer(dt)->guard();
......@@ -1787,11 +1797,11 @@ namespace fmwkng {
if (p_ == phase::LEAD_IN)
{
impl::thread_pointer(dt)->rendezvous(dt);
impl::thread_pointer(dt)->template push_element<my_tag, element_sense::OPEN>();
push_config_open(dt);
}
if (p_ == phase::TEST)
{
impl::thread_pointer(dt)->template push_element<my_tag, element_sense::OPEN>();
push_config_open(dt);
start_ = clock::now();
}
}
......@@ -1803,25 +1813,37 @@ namespace fmwkng {
{
stop_ = clock::now();
delta_ = stop_ - start_;
auto delta_cnt = delta_.count();
auto delta_recalculated = (double)delta_cnt / (complexity(dt) * count_sum_);
push_config_close(dt);
impl::thread_pointer(dt)->template push_element<my_tag, element_sense::CLOSE>(delta_recalculated);
}
if (p_ == phase::LEAD_OUT)
{
push_config_close(dt);
impl::thread_pointer(dt)->template push_element<my_tag, element_sense::CLOSE>(delta_);
avg_delta_ = impl::thread_pointer(dt)->rendezvous_average(dt, delta_.count());
auto delta_cnt = delta_.count();
avg_delta_ = impl::thread_pointer(dt)->rendezvous_average(dt, delta_cnt);
}
}
template< typename dt_t>
auto complexity(const dt_t& dt)
{
auto c = measurement_policy::complexity(temporary_context(dt.get_parent_pointer_tuple()));
return std::max<decltype(c)>(c, 1);
}
};
template< typename ... range_tags>
struct data_policy< measurement_tag_category, auto_measurement_tag< range_tags ...>> {
using type = auto_measurement_data_holder< range_tags ...>;
template< typename measurement_policy>
struct data_policy< measurement_tag_category, auto_measurement_tag< measurement_policy>> {
using type = auto_measurement_data_holder< measurement_policy>;
};
#pragma endregion
}
#pragma region tagged_context1
template< typename ... tags>
class tagged_context;
template< typename dt_t>
class temporary_context;
#pragma endregion
namespace impl {
#pragma region parallel2
......@@ -1859,6 +1881,40 @@ namespace fmwkng {
thread_functor(const impl::data_tuple< tags...>&, F&& f)->thread_functor< std::remove_cv_t<std::remove_reference_t<F>>, tags ...>;
#pragma endregion
}
#pragma region temporary_context
template< typename ppt_t>
class temporary_context {
private:
using self_ = temporary_context< ppt_t>;
public:
temporary_context(const ppt_t& ppt)
: ppt_(ppt)
{}
template< typename range_tag>
auto get() const
{
auto p = std::get<const impl::data_holder<range_tag>*>(ppt_);
return p->value();
}
/*
template< typename range_tag>
auto count() const
{
using value_type = impl::enumerator_value_t<range_tag>;
using controller_category = impl::controller_tag_category< range_tag>;
auto root = impl::category_pointer<controller_category>(*dt_);
auto&& my_config = root->template get_range_config<range_tag>().config;
return my_config.count();
}
*/
private:
ppt_t ppt_;
};
#pragma endregion
#pragma region tagged_context2
template< typename ... tags>
class tagged_context : impl::immovable {
......@@ -1921,7 +1977,7 @@ namespace fmwkng {
std::size_t n_continue = 0;
std::size_t n_average = 0;
impl::average_t sum_average = 0;
average_t sum_average = 0;
for (auto&& rv : rvs)
{
switch (rv.index()) {
......@@ -2000,10 +2056,10 @@ namespace fmwkng {
return child_context(dt_.get_my_pointer(), dt_.get_parent_pointer_tuple());
}
template< typename ... range_tags>
template< typename measurement_policy>
auto auto_measurement(std::size_t v_last) const
{
using my_measurement_tag = impl::auto_measurement_tag< range_tags ...>;
using my_measurement_tag = impl::auto_measurement_tag< measurement_policy>;
using child_context = tagged_context< my_measurement_tag, tags ...>;
using diff_t = impl::enumerator_value_t<my_measurement_tag>;
......@@ -2027,6 +2083,13 @@ namespace fmwkng {
return rv ? this : nullptr;
}
template< typename range_tag>
auto get() const
{
auto p = dt_.template get_pointer<range_tag>();
return p->value();
}
template< typename range_tag>
auto count() const
{
......@@ -2163,7 +2226,7 @@ namespace fmwkng {
{}
auto_repeat(const auto_repeat & base, value_type multiplier, value_type divisor)
: v_count_(base.v_count_ * multiplier / divisor)
: v_count_(std::max<value_type>(base.v_count_ * multiplier / divisor, 1))
{}
void set_arg(std::string_view s)
......@@ -2284,12 +2347,24 @@ namespace fmwkng {
return ctx.template get< range_tag>();
}
template< typename range_tag, typename dt_t>
auto get(const temporary_context< dt_t>& ctx)
{
return ctx.template get< range_tag>();
}
template< typename range_tag, typename ... tags>
auto count(const tagged_context< tags ...>& ctx)
{
return ctx.template count< range_tag>();
}
/*
template< typename range_tag, typename dt_t>
auto count(const temporary_context< dt_t>& ctx)
{
return ctx.template count< range_tag>();
}
*/
template< typename range_tag, typename ... tags>
auto for_index(const tagged_context< tags ...>& ctx)
{
......@@ -2314,10 +2389,10 @@ namespace fmwkng {
return ctx.measurement();
}
template< typename range_tag, typename ... tags>
template< typename measurement_policy, typename ... tags>
auto auto_measurement(const tagged_context< tags ...>& ctx, std::size_t v_last)
{
return ctx.template auto_measurement< range_tag>( v_last);
return ctx.template auto_measurement< measurement_policy>( v_last);
}
template< typename ... tags>
......
......@@ -37,20 +37,63 @@ namespace levenmain {
};
#endif
struct a_size {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "a_size"; }
static auto enumerator() {
return fmwkng::logarithmic(
0x40,
#ifdef NDEBUG
0x10000,
#else
0x1000,
#endif
0x4
);
}
};
struct b_size {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "b_size"; }
static auto enumerator() {
return fmwkng::logarithmic(
0x40,
#ifdef NDEBUG
0x10000,
#else
0x1000,
#endif
0x4
);
}
};
struct repeats {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "repeats"; }
static auto enumerator() {
return fmwkng::auto_repeat(
#ifdef NDEBUG
50000
0x10000000
#else
1000
0x100000
#endif
);
}
};
struct repeat_policy {
using ranges = fmwkng::ranges< repeats>;
static auto name() { return "time_per_cell"; }
template< typename CTX>
static auto complexity(CTX&& ctx)
{
return (std::uint_fast64_t)fmwkng::get<a_size>(ctx) * fmwkng::get<b_size>(ctx);
}
static constexpr fmwkng::average_t minimum_count = 1000000000ULL;
};
struct output {
using tag_category = fmwkng::result_tag_category;
static auto name() { return "output"; }
......@@ -69,7 +112,7 @@ namespace levenmain {
, platform_avx512
#endif
>;
using ranges = fmwkng::ranges<repeats>;
using ranges = fmwkng::ranges<a_size, b_size, repeats>;
};
struct run_thread_ftor {
......@@ -78,25 +121,29 @@ namespace levenmain {
{
using namespace fmwkng;
using policy = typename platform_t<decltype(ctx2)>::policy;
for (auto&& ctx3 : for_range<a_size>(ctx2))
{
generator_4 mg(
policy_random(
std::mt19937_64::default_seed + ctx2.thread_index()
), 100, 100);
for (auto&& ctx4 : for_range<b_size>(ctx3))
{
generator_4 mg(
policy_random(
std::mt19937_64::default_seed + ctx2.thread_index()
), get<a_size>(ctx4), get<b_size>(ctx4));
levensol::levenstein<policy> data(mg.begin1(), mg.end1(), mg.begin2(), mg.end2());
levensol::levenstein<policy> data(mg.begin1(), mg.end1(), mg.begin2(), mg.end2());
for (auto&& ctx5 : auto_measurement<repeats>(ctx2, 1024))
{
std::size_t h = 0;
for (auto i : for_index<repeats>(ctx5))
{
auto rv = data.compute();
h = rv;
}
if (stop_for_results(ctx5))
for (auto&& ctx5 : auto_measurement<repeat_policy>(ctx4, 1024))
{
store_result<output>(ctx5, h);
std::size_t h = 0;
for (auto i : for_index<repeats>(ctx5))
{
auto rv = data.compute();
h = rv;
}
if (stop_for_results(ctx5))
{
store_result<output>(ctx5, h);
}
}
}
}
......
......@@ -38,20 +38,44 @@ namespace macromain {
};
#endif
struct nonmacro_weight {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "nonmacro_weight"; }
static auto enumerator() {
return fmwkng::logarithmic(3, 48, 2);
}
};
struct exp_width {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "exp_width"; }
static auto enumerator() {
return fmwkng::logarithmic(3, 12, 2);
}
};
struct lines {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "lines"; }
static auto enumerator() {
return fmwkng::auto_repeat(
#ifdef NDEBUG
50000
480000
#else
1000
48000
#endif
);
}
};
struct line_policy {
using ranges = fmwkng::ranges< lines>;
static auto name() { return "time_per_line"; }
template< typename CTX>
static auto complexity(CTX&& ctx) { return fmwkng::get<exp_width>(ctx); }
static constexpr fmwkng::average_t minimum_count = 1000000000ULL;
};
struct dump {
using tag_category = fmwkng::range_tag_category;
static auto name() { return "dump"; }
......@@ -78,7 +102,7 @@ namespace macromain {
, platform_avx512
#endif
>;
using ranges = fmwkng::ranges<lines, dump>;
using ranges = fmwkng::ranges<nonmacro_weight, exp_width, lines, dump>;
};
struct run_thread_ftor {
......@@ -86,63 +110,70 @@ namespace macromain {
void operator()(CTX&& ctx2) const
{
using namespace fmwkng;
for ( auto && ctx3 : for_range<nonmacro_weight>(ctx2) )
{
//auto ctx3 = measurement(ctx2);
macroasgn::macrotext_generator mg(
std::mt19937_64::default_seed + ctx2.thread_index()
, 3, 10, 1021, 8, 3, 3, 5, 0);
if ( count<dump>(ctx2))
for (auto&& ctx4 : for_range<exp_width>(ctx3))
{
mg.advance(1000);
auto flags = platform_t<decltype(ctx2)>::name() + std::string(".") + std::to_string(ctx2.thread_index());
auto ifn = "input." + flags + ".txt";
auto ofn = "output." + flags + ".txt";
std::ofstream is(ifn);
std::ofstream os(ofn);
macroasgn::macrotext_generator mg(
std::mt19937_64::default_seed + ctx4.thread_index()
, 3, 100, 1021, 8, 3, get<nonmacro_weight>(ctx4), get<exp_width>(ctx4), 1);
if (count<dump>(ctx4))
{
auto g = guard(ctx2);
std::cout << "Dumping\t" << ifn << "\t" << ofn << std::endl;
}
mg.advance(1000);
auto flags = std::to_string(get<nonmacro_weight>(ctx4))
+ "." + std::to_string(get<exp_width>(ctx4))
+ "." + std::string(platform_t<decltype(ctx4)>::name())
+ "." + std::to_string(ctx4.thread_index());
auto ifn = "input." + flags + ".txt";
auto ofn = "output." + flags + ".txt";
std::ofstream is(ifn);
std::ofstream os(ofn);
macrosol::macroprocessor< macrosol::policy_scalar> mp;
std::string output;
for (;;)
{
auto rv = mg.getline();
if (!rv)
break;
is << *rv << std::endl;
output.clear();
auto rv2 = mp.process(*rv, output);
if (rv2)
{
os << output << std::endl;
auto g = guard(ctx4);
std::cout << "Dumping\t" << ifn << "\t" << ofn << std::endl;
}
macrosol::macroprocessor< macrosol::policy_scalar> mp;
std::string output;
for (;;)
{
auto rv = mg.getline();
if (!rv)
break;
is << *rv << std::endl;
output.clear();
auto rv2 = mp.process(*rv, output);
if (rv2)
{
os << output << std::endl;
}
}
}
}
for (auto&& ctx5 : auto_measurement<lines>(ctx2, 1024))
{
macrosol::macroprocessor< macrosol::policy_scalar> mp;
mg.rewind();
mg.advance(count<lines>(ctx5));
std::size_t h = 0;
std::string output;
for (;;)
{
auto rv = mg.getline();
if (!rv)
break;
output.clear();
auto rv2 = mp.process(*rv, output);
if (rv2)
h += std::hash<std::string>()(output);
}
if (stop_for_results(ctx5))
for (auto&& ctx5 : auto_measurement<line_policy>(ctx4, 1024))
{
store_result<output_hash>(ctx5, h);
macrosol::macroprocessor< macrosol::policy_scalar> mp;
mg.rewind();
mg.advance(count<lines>(ctx5));
std::size_t h = 0;
std::string output;
for (;;)
{
auto rv = mg.getline();
if (!rv)
break;
output.clear();
auto rv2 = mp.process(*rv, output);
if (rv2)
h += std::hash<std::string>()(output);
}
if (stop_for_results(ctx5))
{
store_result<output_hash>(ctx5, h);
}
}
}
}
}
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment