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
Philip Trettner
tg-samples
Commits
414efe98
Commit
414efe98
authored
Mar 09, 2020
by
Philip Trettner
Browse files
Merge branch 'feature/cleanup-fixed_int' into 'develop'
Feature/cleanup fixed int See merge request
!31
parents
d9c8fbd1
e232f888
Pipeline
#13729
passed with stage
in 6 minutes and 14 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
typed-geometry
@
d6bdfdd3
Subproject commit
1d9862713da6b845580b378275cd2c02382a16d4
Subproject commit
d6bdfdd3de932143316d9afc850bbfa8c1c6010d
tests/feature/fixed_int/fixed_int.cc
View file @
414efe98
...
...
@@ -423,7 +423,6 @@ TG_FUZZ_TEST(TypedGeometry, FixedIntMul)
check_mul
<
2
,
2
,
1
>
(
rng
);
check_mul
<
2
,
2
,
2
>
(
rng
);
check_mul
<
3
,
1
,
1
>
(
rng
);
check_mul
<
3
,
1
,
2
>
(
rng
);
check_mul
<
3
,
2
,
1
>
(
rng
);
check_mul
<
3
,
2
,
2
>
(
rng
);
...
...
@@ -433,9 +432,6 @@ TG_FUZZ_TEST(TypedGeometry, FixedIntMul)
check_mul
<
3
,
3
,
2
>
(
rng
);
check_mul
<
3
,
3
,
3
>
(
rng
);
check_mul
<
4
,
1
,
1
>
(
rng
);
check_mul
<
4
,
1
,
2
>
(
rng
);
check_mul
<
4
,
2
,
1
>
(
rng
);
check_mul
<
4
,
2
,
2
>
(
rng
);
check_mul
<
4
,
1
,
3
>
(
rng
);
check_mul
<
4
,
3
,
1
>
(
rng
);
...
...
tests/feature/fixed_int/fixed_uint.cc
View file @
414efe98
...
...
@@ -355,7 +355,6 @@ TG_FUZZ_TEST(TypedGeometry, FixedUintMul)
check_mul
<
2
,
2
,
1
>
(
rng
);
check_mul
<
2
,
2
,
2
>
(
rng
);
check_mul
<
3
,
1
,
1
>
(
rng
);
check_mul
<
3
,
1
,
2
>
(
rng
);
check_mul
<
3
,
2
,
1
>
(
rng
);
check_mul
<
3
,
2
,
2
>
(
rng
);
...
...
@@ -365,9 +364,6 @@ TG_FUZZ_TEST(TypedGeometry, FixedUintMul)
check_mul
<
3
,
3
,
2
>
(
rng
);
check_mul
<
3
,
3
,
3
>
(
rng
);
check_mul
<
4
,
1
,
1
>
(
rng
);
check_mul
<
4
,
1
,
2
>
(
rng
);
check_mul
<
4
,
2
,
1
>
(
rng
);
check_mul
<
4
,
2
,
2
>
(
rng
);
check_mul
<
4
,
1
,
3
>
(
rng
);
check_mul
<
4
,
3
,
1
>
(
rng
);
...
...
tests/feature/fixed_int/generate_fixed_uint_multiplications.cc
View file @
414efe98
...
...
@@ -6,6 +6,30 @@
namespace
{
[[
maybe_unused
]]
std
::
string
imul
()
{
return
"inline u64 imul(u64 lhs, u64 rhs, u64* high)
\n
"
"{
\n
"
"#ifdef _MSC_VER
\n
"
" return _mul128(lhs, rhs, &(i64(high)));
\n
"
"#else
\n
"
" __int128 res_i = __int128(i64(lhs)) * i64(rhs);
\n
"
" u64 v[2] = {};
\n
"
" memcpy(&v, &res_i, sizeof(__int128));
\n
"
" *high = v[1];
\n
"
" return v[0];
\n
"
"#endif
\n
"
"}
\n
"
;
}
[[
maybe_unused
]]
std
::
string
mul
()
{
return
"inline u64 mul(u64 lhs, u64 rhs, u64* high)
\n
"
"{
\n
"
" return _mulx_u64(lhs, rhs, high);
\n
"
"}
\n
"
;
}
std
::
string
generate_mul
(
int
w_r
,
int
w_a
,
int
w_b
)
{
auto
const
out_type
=
"u"
+
std
::
to_string
(
w_r
*
64
);
...
...
@@ -59,10 +83,9 @@ std::string generate_mul(int w_r, int w_a, int w_b)
}
std
::
string
result
;
result
+=
"template<>
\n
"
;
// result += "inline fixed_uint<" + std::to_string(w_r) + "> mul(" + a_type + (w_a > 1 ? " const&" : "") + " lhs, " + b_type + (w_b > 1 ? " const&" : "") + " rhs)\n{\n";
result
+=
"inline fixed_uint<"
+
std
::
to_string
(
w_r
)
+
"> mul("
+
a_type
+
" const&"
+
" lhs, "
+
b_type
+
" const&"
+
" rhs)
\n
{
\n
"
;
result
+=
" fixed_uint<"
+
std
::
to_string
(
w_r
)
+
"> res;
\n
"
;
result
+=
"template <>
\n
"
;
result
+=
"inline "
+
out_type
+
" mul("
+
a_type
+
" lhs, "
+
b_type
+
" rhs)
\n
{
\n
"
;
result
+=
" "
+
out_type
+
" res;
\n
"
;
for
(
auto
i
=
0u
;
i
<
vars_l
.
size
();
++
i
)
result
+=
" u64 "
+
l_of
(
vars_l
[
i
])
+
" = 0;
\n
"
;
...
...
@@ -107,6 +130,63 @@ std::string generate_mul(int w_r, int w_a, int w_b)
return
result
;
}
/// special case
std
::
string
imul_128_64_128
()
{
return
"template <>
\n
"
"inline i128 imul(i64 lhs, i128 rhs)
\n
"
"{
\n
"
"#ifdef _MSC_VER
\n
"
" return imul<2>(i128(lhs), rhs);
\n
"
"#else
\n
"
" intrinsic_i128 l = lhs;
\n
"
" intrinsic_i128 r;
\n
"
" memcpy(&r, &rhs, sizeof(intrinsic_i128));
\n
"
" intrinsic_i128 inres = l * r;
\n
"
" i128 res;
\n
"
" memcpy(&res, &inres, sizeof(intrinsic_i128));
\n
"
" return res;
\n
"
"#endif
\n
"
"}
\n
"
;
}
std
::
string
imul_128_128_64
()
{
return
"template <>
\n
"
"inline i128 imul(i128 lhs, i64 rhs)
\n
"
"{
\n
"
"#ifdef _MSC_VER
\n
"
" return imul<2>(lhs, i128(rhs));
\n
"
"#else
\n
"
" intrinsic_i128 l;
\n
"
" intrinsic_i128 r = rhs;
\n
"
" memcpy(&l, &lhs, sizeof(intrinsic_i128));
\n
"
" intrinsic_i128 inres = l * r;
\n
"
" i128 res;
\n
"
" memcpy(&res, &inres, sizeof(intrinsic_i128));
\n
"
" return res;
\n
"
"#endif
\n
"
"}
\n
"
;
}
std
::
string
imul_128_64_64
()
{
return
"template <>
\n
"
"inline i128 imul(i64 lhs, i64 rhs)
\n
"
"{
\n
"
"#ifdef _MSC_VER
\n
"
" return imul<2>(i128(lhs), i128(rhs));
\n
"
"#else
\n
"
" intrinsic_i128 l = lhs;
\n
"
" intrinsic_i128 r = rhs;
\n
"
" intrinsic_i128 inres = l * r;
\n
"
" i128 res;
\n
"
" memcpy(&res, &inres, sizeof(intrinsic_i128));
\n
"
" return res;
\n
"
"#endif
\n
"
"}
\n
"
;
}
std
::
string
generate_imul
(
int
w_r
,
int
w_a
,
int
w_b
)
{
auto
const
out_type
=
"i"
+
std
::
to_string
(
w_r
*
64
);
...
...
@@ -124,15 +204,15 @@ std::string generate_imul(int w_r, int w_a, int w_b)
auto
const
h_of
=
[](
std
::
pair
<
int
,
int
>
const
&
pair
)
{
return
"h"
+
std
::
to_string
(
pair
.
first
)
+
std
::
to_string
(
pair
.
second
);
};
auto
const
lhs_of
=
[
&
](
int
v
)
{
if
(
w_a
==
1
)
return
std
::
string
(
"l"
);
return
std
::
string
(
"l
hs
"
);
else
return
"l.d["
+
std
::
to_string
(
v
)
+
"]"
;
return
"l
hs
.d["
+
std
::
to_string
(
v
)
+
"]"
;
};
auto
const
rhs_of
=
[
&
](
int
v
)
{
if
(
w_b
==
1
)
return
std
::
string
(
"r"
);
return
std
::
string
(
"r
hs
"
);
else
return
"r.d["
+
std
::
to_string
(
v
)
+
"]"
;
return
"r
hs
.d["
+
std
::
to_string
(
v
)
+
"]"
;
};
for
(
auto
i
=
0
;
i
<
w_a
;
++
i
)
...
...
@@ -173,19 +253,20 @@ std::string generate_imul(int w_r, int w_a, int w_b)
result
+=
" }
\n
"
;
};
result
+=
"template<>
\n
"
;
result
+=
"inline
fixed_int<"
+
std
::
to_string
(
w_r
)
+
"
>
imul("
+
a_type
+
"
const&"
+
"
lhs, "
+
b_type
+
"
const&"
+
"
rhs)
\n
{
\n
"
;
result
+=
"template
<>
\n
"
;
result
+=
"inline
"
+
out_type
+
" imul("
+
a_type
+
" lhs, "
+
b_type
+
" rhs)
\n
{
\n
"
;
// result += "fixed_int<" + std::to_string(w_r) + "> imul(" + a_type + (w_a > 1 ? " const&" : "") + " lhs, " + b_type + (w_b > 1 ? " const&" : "") + " rhs)\n{\n";
result
+=
"
fixed_int<"
+
std
::
to_string
(
w_r
)
+
"
>
res;
\n
"
;
result
+=
"
"
+
out_type
+
" res;
\n
"
;
result
+=
" "
+
a_type
+
" l = lhs;
\n
"
;
result
+=
" "
+
b_type
+
" r = rhs;
\n
"
;
result
+=
" u64 s_l = u64(i64("
+
lhs_of
(
w_a
-
1
)
+
") >> 63); // 0 iff > 0, -1 otherwise
\n
"
;
result
+=
" u64 s_r = u64(i64("
+
rhs_of
(
w_b
-
1
)
+
") >> 63); // 0 iff > 0, -1 otherwise
\n
"
;
result
+=
" u64 s_res = s_l ^ s_r;
\n
"
;
// conditional inversion
conditional_invert
(
lhs_of
,
"s_l"
,
w_a
);
conditional_invert
(
rhs_of
,
"s_r"
,
w_b
);
if
(
w_a
!=
w_b
||
w_a
!=
w_r
)
{
result
+=
" u64 s_l = u64(i64("
+
lhs_of
(
w_a
-
1
)
+
") >> 63); // 0 iff > 0, -1 otherwise
\n
"
;
result
+=
" u64 s_r = u64(i64("
+
rhs_of
(
w_b
-
1
)
+
") >> 63); // 0 iff > 0, -1 otherwise
\n
"
;
result
+=
" u64 s_res = s_l ^ s_r;
\n
"
;
conditional_invert
(
lhs_of
,
"s_l"
,
w_a
);
conditional_invert
(
rhs_of
,
"s_r"
,
w_b
);
}
for
(
auto
i
=
0u
;
i
<
vars_l
.
size
();
++
i
)
result
+=
" u64 "
+
l_of
(
vars_l
[
i
])
+
" = 0;
\n
"
;
...
...
@@ -224,7 +305,8 @@ std::string generate_imul(int w_r, int w_a, int w_b)
}
result
+=
";
\n
"
;
conditional_invert
([](
int
i
)
{
return
"res.d["
+
std
::
to_string
(
i
)
+
"]"
;
},
"s_res"
,
w_r
);
if
(
w_a
!=
w_b
||
w_a
!=
w_r
)
conditional_invert
([](
int
i
)
{
return
"res.d["
+
std
::
to_string
(
i
)
+
"]"
;
},
"s_res"
,
w_r
);
result
+=
" return res;
\n
"
;
result
+=
"}
\n
"
;
...
...
@@ -247,17 +329,18 @@ void generate_mul_file()
file
<<
"#include <x86intrin.h>
\n
"
;
file
<<
"#endif
\n\n
"
;
file
<<
"#include <typed-geometry/feature/fixed_
u
int.hh>
\n\n
"
;
file
<<
"#include <typed-geometry/feature/fixed_int.hh>
\n\n
"
;
file
<<
"namespace tg::detail
\n
{
\n
"
;
file
<<
"template <int w_res, class T0, class T1>
\n
"
;
file
<<
"fixed_uint<w_res> mul(T0 const& lhs, T1 const& rhs);
\n\n
"
;
for
(
auto
r
=
2
;
r
<=
4
;
++
r
)
for
(
auto
j
=
1
;
j
<=
4
;
++
j
)
for
(
auto
i
=
1
;
i
<=
4
;
++
i
)
{
file
<<
generate_mul
(
r
,
i
,
j
);
file
<<
"
\n
"
;
}
for
(
auto
j
=
1
;
j
<=
r
;
++
j
)
for
(
auto
i
=
1
;
i
<=
r
;
++
i
)
if
(
i
+
j
>=
r
)
{
file
<<
generate_mul
(
r
,
i
,
j
);
file
<<
"
\n
"
;
}
file
<<
"} // namespace tg::detail"
;
}
...
...
@@ -274,24 +357,40 @@ void generate_imul_file()
file
<<
"#include <intrin.h>
\n
"
;
file
<<
"#else
\n
"
;
file
<<
"#include <x86intrin.h>
\n
"
;
file
<<
"#include <cstring>
\n
"
;
file
<<
"#endif
\n\n
"
;
file
<<
"#include <typed-geometry/feature/fixed_int.hh>
\n\n
"
;
file
<<
"namespace tg::detail
\n
{
\n
"
;
file
<<
"template <int w_res, class T0, class T1>
\n
"
;
file
<<
"fixed_int<w_res> imul(T0 const& lhs, T1 const& rhs);
\n\n
"
;
for
(
auto
r
=
2
;
r
<=
4
;
++
r
)
for
(
auto
j
=
1
;
j
<=
4
;
++
j
)
for
(
auto
i
=
1
;
i
<=
4
;
++
i
)
{
file
<<
generate_imul
(
r
,
i
,
j
);
file
<<
"
\n
"
;
}
// gcc / msvc special case
file
<<
"/// GCC warns that __int128 is not iso-c++
\n
"
"#ifndef _MSC_VER // MSVC does not support __int128
\n
"
"#pragma GCC diagnostic push
\n
"
"#pragma GCC diagnostic ignored
\"
-Wpedantic
\"\n
"
"using intrinsic_i128 = __int128;
\n
"
"#pragma GCC diagnostic pop
\n
"
"#endif
\n\n
"
;
// special cases
// msvc requires this one to come first
file
<<
generate_imul
(
2
,
2
,
2
)
<<
"
\n
"
;
file
<<
imul_128_64_64
()
<<
"
\n
"
;
file
<<
imul_128_128_64
()
<<
"
\n
"
;
file
<<
imul_128_64_128
()
<<
"
\n
"
;
for
(
auto
r
=
3
;
r
<=
4
;
++
r
)
for
(
auto
j
=
1
;
j
<=
r
;
++
j
)
for
(
auto
i
=
1
;
i
<=
r
;
++
i
)
if
(
i
+
j
>=
r
)
{
file
<<
generate_imul
(
r
,
i
,
j
);
file
<<
"
\n
"
;
}
file
<<
"} // namespace tg::detail"
;
}
}
// namespace
TEST_CASE
(
"tg generate multiplications"
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment