Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Klepl Jiří
asgn
Commits
f7b2d14e
Commit
f7b2d14e
authored
Mar 15, 2020
by
Bednárek David RNDr. Ph.D.
Browse files
aggregation partially works
parent
7ced1c58
Changes
3
Hide whitespace changes
Inline
Side-by-side
asgn/fmwkng.hpp
View file @
f7b2d14e
...
...
@@ -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_
;