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
80522e54
Commit
80522e54
authored
Mar 19, 2020
by
Bednárek David RNDr. Ph.D.
Browse files
gold check files
parent
421aae31
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
asgn/CMakeLists.txt
View file @
80522e54
...
...
@@ -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"
"levengold
debug.cpp"
"levengold.cpp"
"levengoldbig
.cpp"
)
asgn/fmwkng.hpp
View file @
80522e54
...
...
@@ -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
}
...
...
asgn/levenasgn.hpp
View file @
80522e54
...
...
@@ -156,13 +156,13 @@ namespace levenmain {
static
auto
code_name
()
{
return
"levenmain::a_size"
;
}
static
auto
enumerator
()
{
return
fmwkng
::
logarithmic
(
0x
4
0
,
0x
8
0
,
#ifdef NDEBUG
0x
10
000
,
0x
8
000
,
#else
0x
10
00
,
0x
8
00
,
#endif
0x
2
0
0x
1
0
);
}
};
...
...
@@ -173,13 +173,13 @@ namespace levenmain {
static
auto
code_name
()
{
return
"levenmain::b_size"
;
}
static
auto
enumerator
()
{
return
fmwkng
::
logarithmic
(
0x
4
0
,
0x
8
0
,
#ifdef NDEBUG
0x
10
000
,
0x
8
000
,
#else
0x
10
00
,
0x
8
00
,
#endif
0x
2
0
0x
1
0
);
}
};
...
...
@@ -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
#else