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

aggregation partially works

parent 7ced1c58
......@@ -20,6 +20,7 @@
#include <type_traits>
#include <variant>
#include <cstdlib>
#include <sstream>
namespace fmwkng {
namespace impl {
......@@ -46,19 +47,57 @@ namespace fmwkng {
virtual void data_text(std::ostream& os, std::size_t i) const = 0;
virtual void metadata_marker(std::ostream& os) const = 0;
virtual bool useful() const = 0;
virtual bool reducible() const = 0;
virtual void aggregate_with(const abstract_element* other) = 0;
virtual element_sense sense() const = 0;
};
class element_list {
using element_vector = std::vector< element_ptr>;
using element_const_iterator = element_vector::const_iterator;
class element_list;
class element_list_view {
private:
inline static element_vector empty_;
public:
void push_back(element_ptr&& ep)
element_list_view()
{
ev_.push_back(std::move(ep));
static element_vector empty_;
b_ = empty_.begin();
e_ = empty_.end();
}
element_list_view(element_const_iterator b, element_const_iterator e)
: b_(b), e_(e)
{}
element_const_iterator begin() const
{
return b_;
}
element_const_iterator end() const
{
return e_;
}
std::size_t size() const
{
return e_ - b_;
}
const abstract_element* operator[](std::size_t i) const
{
return &*b_[i];
}
element_list clone() const;
std::size_t data_size() const
{
std::size_t s = 0;
for (auto&& a : ev_)
for (auto&& a : *this)
{
s += a->data_size();
}
......@@ -67,7 +106,7 @@ namespace fmwkng {
void data_text(std::ostream& os) const
{
std::size_t s = 0;
for (auto&& a : ev_)
for (auto&& a : *this)
{
auto n = a->data_size();
for (std::size_t i = 0; i < n; ++i)
......@@ -82,7 +121,7 @@ namespace fmwkng {
void metadata_text(std::ostream& os) const
{
std::size_t s = 0;
for (auto&& a : ev_)
for (auto&& a : *this)
{
a->metadata_marker(os);
}
......@@ -90,7 +129,7 @@ namespace fmwkng {
bool has_paired() const
{
for (auto&& a : ev_)
for (auto&& a : *this)
{
if (a->sense() == element_sense::CLOSE)
return true;
......@@ -98,15 +137,84 @@ namespace fmwkng {
return false;
}
virtual bool useful() const
bool useful() const
{
for (auto&& a : ev_)
for (auto&& a : *this)
{
if (a->useful())
return true;
}
return false;
}
private:
element_const_iterator b_;
element_const_iterator e_;
};
class element_list {
public:
operator element_list_view() const
{
return element_list_view(ev_.begin(), ev_.end());
}
element_const_iterator begin() const
{
return ev_.begin();
}
element_const_iterator end() const
{
return ev_.end();
}
std::size_t size() const
{
return ev_.size();
}
bool empty() const
{
return ev_.empty();
}
abstract_element* operator[](std::size_t i)
{
return &*ev_[i];
}
void push_back(element_ptr&& ep)
{
ev_.push_back(std::move(ep));
}
void push_back(element_list&& el)
{
ev_.insert(ev_.end(), std::make_move_iterator(el.ev_.begin()), std::make_move_iterator(el.ev_.end()));
}
std::size_t data_size() const
{
return element_list_view(*this).data_size();
}
void data_text(std::ostream& os) const
{
element_list_view(*this).data_text(os);
}
void metadata_text(std::ostream& os) const
{
element_list_view(*this).metadata_text( os);
}
bool has_paired() const
{
return element_list_view(*this).has_paired();
}
bool useful() const
{
return element_list_view(*this).useful();
}
void clear_paired()
{
......@@ -127,15 +235,210 @@ namespace fmwkng {
}
}
private:
std::vector< element_ptr> ev_;
element_vector ev_;
};
element_list element_list_view::clone() const
{
element_list el;
for (auto&& a : *this)
{
el.push_back(a->clone());
}
return el;
}
template< typename tag_category, typename tag, element_sense sense>
struct element_traits;
template< typename tag, element_sense sense>
using element_traits_t = element_traits< typename tag::tag_category, tag, sense>;
void print_list(element_list_view el, element_list_view prefix = {})
{
prefix.metadata_text(std::cout);
el.metadata_text(std::cout);
if (prefix.data_size())
{
std::cout << '\t';
prefix.data_text(std::cout);
}
if (el.data_size())
{
std::cout << '\t';
el.data_text(std::cout);
}
std::cout << std::endl;
}
struct reducer_node;
using reducer_list = std::vector< reducer_node>;
using reduced_list = std::vector< element_list>;
struct reducer_node {
element_list_view source_range;
reducer_list children;
element_list reduced_children;
};
reducer_list view_to_list(element_const_iterator & b, element_const_iterator e)
{
reducer_list rl;
while (b != e && (*b)->sense() == element_sense::OPEN)
{
auto b1 = b;
++b;
reducer_node rn1;
rn1.children = view_to_list(b, e);
assert(b != e);
assert((*b)->sense() == element_sense::CLOSE);
++b;
rn1.source_range = element_list_view(b1, b);
rl.push_back(std::move(rn1));
}
return rl;
}
void print_list(std::ostream& os, reducer_list& rl, const std::string& indent = {})
{
for (auto&& a : rl)
{
os << indent;
(*a.source_range.begin())->metadata_marker(os);
os << "\t";
a.source_range.metadata_text(os);
os << std::endl;
print_list(os, a.children, indent + "\t");
os << indent;
(*(a.source_range.end()-1))->metadata_marker(os);
os << std::endl;
}
}
std::size_t deepest_reducible(const reducer_list& rl)
{
std::size_t m = 0;
for (auto&& a : rl)
{
if ((*a.source_range.begin())->reducible())
{
m = std::max< std::size_t>(m, 0);
}
else
{
m = std::max< std::size_t>(m, 1 + deepest_reducible(a.children));
}
}
return m;
}
void reduce_list(reduced_list& nl, const reducer_list &rl)
{
std::unordered_map< std::string, element_list> reduction_map;
std::vector< std::unordered_map< std::string, element_list>::pointer> reduction_order;
for (auto&& a : rl)
{
element_list_view src = a.source_range;
if (!a.reduced_children.empty())
src = a.reduced_children;
std::ostringstream oss;
src.metadata_text(oss);
auto n = oss.str();
auto rv = reduction_map.try_emplace(std::move(n));
if (rv.second)
{
// first seen
reduction_order.push_back(&*rv.first);
rv.first->second = src.clone();
}
else
{
auto sz = rv.first->second.size();
assert(sz == src.size());
for (std::size_t i = 0; i < sz; ++i)
{
rv.first->second[i]->aggregate_with(src[i]);
}
}
}
for (auto p : reduction_order)
{
nl.push_back(std::move(p->second));
}
}
void reduce_node(reducer_node& rn, std::size_t depth)
{
if (depth != 0)
{
if (!(*rn.source_range.begin())->reducible())
{
for (auto&& a : rn.children)
{
reduce_node(a, depth - 1);
}
}
}
else
{
std::cout << "Reducing \t";
print_list(rn.source_range);
reduced_list nl;
reduce_list(nl, rn.children);
rn.reduced_children.push_back((*rn.source_range.begin())->clone());
for (auto&& a : nl)
{
rn.reduced_children.push_back(std::move(a));
}
rn.reduced_children.push_back((*(rn.source_range.end()-1))->clone());
std::cout << "\t";
print_list(rn.reduced_children);
}
}
element_list reduce_list(element_list_view el)
{
element_list nel;
reducer_list root = view_to_list( el.begin(), el.end());
auto depth = deepest_reducible(root);
//print_list(std::cout, root);
while (depth > 0)
{
--depth;
for (auto&& a : root)
{
reduce_node(a, depth);
}
}
for (auto&& a : root)
{
print_list(a.reduced_children);
}
return nel;
}
void print_all(element_list_view el, element_list_view prefix = {})
{
print_list(el, prefix);
auto nel = reduce_list(el);
print_list(nel, prefix);
}
template< typename tag, element_sense sense_p, typename data_t>
class element : public abstract_element {
public:
......@@ -167,6 +470,16 @@ namespace fmwkng {
{
return my_traits::useful;
}
virtual bool reducible() const
{
return my_traits::reducible;
}
virtual void aggregate_with(const abstract_element* other)
{
auto p = dynamic_cast<const self_*>(other);
assert(!!p);
my_traits::aggregate(d_, p->d_);
}
private:
using my_traits = element_traits_t<tag, sense_p>;
using self_ = element< tag, sense_p, data_t>;
......@@ -202,6 +515,13 @@ namespace fmwkng {
{
return false;
}
virtual bool reducible() const
{
return my_traits::reducible;
}
virtual void aggregate_with(const abstract_element* other)
{
}
private:
using my_traits = element_traits_t<tag, sense_p>;
using self_ = element< tag, sense_p, void>;
......@@ -253,6 +573,16 @@ namespace fmwkng {
{
return false;
}
virtual bool reducible() const
{
return false;
}
virtual void aggregate_with(const abstract_element* other)
{
auto p = dynamic_cast<const self_*>(other);
assert(!!p);
my_traits::aggregate(d_, p->d_);
}
private:
using self_ = config_element< tag, element_sense::OPEN>;
data_t d_;
......@@ -287,6 +617,13 @@ namespace fmwkng {
{
return false;
}
virtual bool reducible() const
{
return false;
}
virtual void aggregate_with(const abstract_element* other)
{
}
private:
using my_traits = config_element_traits_t<tag>;
using self_ = config_element< tag, element_sense::CLOSE>;
......@@ -830,6 +1167,7 @@ namespace fmwkng {
{
}
using data_type = void;
static constexpr bool reducible = false;
};
template< typename config_t>
......@@ -839,6 +1177,7 @@ namespace fmwkng {
{
}
using data_type = void;
static constexpr bool reducible = false;
};
template< typename config_t>
......@@ -891,6 +1230,7 @@ namespace fmwkng {
{
print_elements();
}
print_all_elements();
}
void flush() const
......@@ -941,17 +1281,20 @@ namespace fmwkng {
template< typename tag, element_sense sense, typename T>
void push_element(T&& t) const
{
el_.push_back(std::make_unique<element_t<tag, sense>>(std::forward<T>(t)));
auto p = std::make_unique<element_t<tag, sense>>(std::forward<T>(t));
push_element_ptr(std::move(p));
}
template< typename tag, element_sense sense>
void push_element() const
{
el_.push_back(std::make_unique<element_t<tag, sense>>());
auto p = std::make_unique<element_t<tag, sense>>();
push_element_ptr(std::move(p));
}
void push_element_ptr(element_ptr && p) const
{
all_el_.push_back(p->clone());
el_.push_back(std::move(p));
}
......@@ -964,6 +1307,7 @@ namespace fmwkng {
typename config_t::ranges::tuple_t range_configs_;
mutable master master_;
mutable element_list el_;
mutable element_list all_el_;
void print_elements() const
{
......@@ -979,6 +1323,11 @@ namespace fmwkng {
}
}
void print_all_elements() const
{
print_all(all_el_);
}
void process_arguments(const std::vector< std::string>& arg)
{
for (auto it = arg.begin(); it != arg.end(); ++it)
......@@ -1004,6 +1353,19 @@ namespace fmwkng {
cfg.config.set_arg(value);
}
});
config_t::platforms::for_each([this, name, value](auto rs) {
using platform_tag = pass_t<decltype(rs)>;
if (name == platform_tag::name())
{
static constexpr auto index = config_t::platforms::template index_v<platform_tag>;
auto&& cfg = std::get<index>(platform_enablers_);
if (value == "1" || value == "true" || value == "on")
cfg = true;
else
cfg = false;
}
});
}
}
......@@ -1081,6 +1443,11 @@ namespace fmwkng {
os << platform_tag::name();
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static void aggregate(data_type&, const data_type&)
{
// NOTHING TO DO WITH MONOSTATE
}
};
template< typename platform_tag>
......@@ -1091,6 +1458,7 @@ namespace fmwkng {
os << ".";
}
using data_type = void;
static constexpr bool reducible = false;
};
template< typename platform_tag>
......@@ -1137,6 +1505,11 @@ namespace fmwkng {
os << d;
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static void aggregate(data_type& r, const data_type& v)
{
r += v; // !!! NONSENSE
}
};
template< typename range_tag>
......@@ -1147,6 +1520,7 @@ namespace fmwkng {
os << ".";
}
using data_type = void;
static constexpr bool reducible = false;
};
template< typename range_tag>
......@@ -1174,6 +1548,10 @@ namespace fmwkng {
{
d.data_text(os);
}
static void aggregate(data_type& r, const data_type& v)
{
r.aggregate(v); // ???
}
};
template< typename tag>
......@@ -1270,6 +1648,11 @@ namespace fmwkng {
os << d;
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
static void aggregate(data_type& r, const data_type& v)
{
r += v; // !!! NONSENSE
}
};
template<>
......@@ -1280,6 +1663,7 @@ namespace fmwkng {
os << ".";
}
using data_type = void;
static constexpr bool reducible = false;
};
class parallel_data_holder {
......@@ -1314,6 +1698,7 @@ namespace fmwkng {
{
print_elements(dt);
}
print_all_elements(dt);
}
template< typename dt_t>
......@@ -1363,17 +1748,20 @@ namespace fmwkng {
template< typename tag, element_sense sense, typename T>
void push_element(T&& t) const
{
el_.push_back(std::make_unique<element_t<tag, sense>>(std::forward<T>(t)));
auto p = std::make_unique<element_t<tag, sense>>(std::forward<T>(t));
push_element_ptr(std::move(p));
}
template< typename tag, element_sense sense>
void push_element() const
{
el_.push_back(std::make_unique<element_t<tag, sense>>());
auto p = std::make_unique<element_t<tag, sense>>();
push_element_ptr(std::move(p));
}
void push_element_ptr(element_ptr && p) const
{
all_el_.push_back(p->clone());
el_.push_back(std::move(p));
}
private:
......@@ -1381,6 +1769,7 @@ namespace fmwkng {
master* master_;
std::size_t index_;
mutable element_list el_;