Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Martin Reinecke
ducc
Commits
59c2ea9c
Commit
59c2ea9c
authored
Jan 14, 2020
by
Martin Reinecke
Browse files
improve morton_utils interface
parent
ee586c1f
Changes
3
Hide whitespace changes
Inline
Side-by-side
mr_util/morton_utils.cc
View file @
59c2ea9c
...
...
@@ -66,11 +66,11 @@ uint32_t block2morton2D_32 (uint32_t v)
return
I
(
utab
[
v
&
0xff
])
|
(
I
(
utab
[(
v
>>
8
)
&
0xff
])
<<
16
)
|
(
I
(
utab
[(
v
>>
16
)
&
0xff
])
<<
1
)
|
(
I
(
utab
[(
v
>>
24
)
&
0xff
])
<<
17
);
}
uint32_t
coord2morton2D_32
(
uint32_t
x
,
uint32_t
y
)
uint32_t
coord2morton2D_32
(
std
::
array
<
uint32_t
,
2
>
x
y
)
{
typedef
uint32_t
I
;
return
I
(
utab
[
x
&
0xff
])
|
(
I
(
utab
[(
x
>>
8
)
&
0xff
])
<<
16
)
|
(
I
(
utab
[
y
&
0xff
])
<<
1
)
|
(
I
(
utab
[(
y
>>
8
)
&
0xff
])
<<
17
);
return
I
(
utab
[
x
y
[
0
]
&
0xff
])
|
(
I
(
utab
[(
x
y
[
0
]
>>
8
)
&
0xff
])
<<
16
)
|
(
I
(
utab
[
xy
[
1
]
&
0xff
])
<<
1
)
|
(
I
(
utab
[(
xy
[
1
]
>>
8
)
&
0xff
])
<<
17
);
}
uint32_t
morton2block2D_32
(
uint32_t
v
)
{
...
...
@@ -81,14 +81,14 @@ uint32_t morton2block2D_32 (uint32_t v)
return
ctab
[
raw1
&
0xff
]
|
(
ctab
[(
raw1
>>
8
)
&
0xff
]
<<
4
)
|
(
ctab
[
raw2
&
0xff
]
<<
16
)
|
(
ctab
[(
raw2
>>
8
)
&
0xff
]
<<
20
);
}
void
morton2coord2D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
)
std
::
array
<
uint32_t
,
2
>
morton2coord2D_32
(
uint32_t
v
)
{
typedef
uint32_t
I
;
I
raw1
=
v
&
0x55555555
,
raw2
=
(
v
>>
1
)
&
0x55555555
;
raw1
|=
raw1
>>
15
;
raw2
|=
raw2
>>
15
;
*
x
=
ctab
[
raw1
&
0xff
]
|
(
ctab
[(
raw1
>>
8
)
&
0xff
]
<<
4
)
;
*
y
=
ctab
[
raw2
&
0xff
]
|
(
ctab
[(
raw2
>>
8
)
&
0xff
]
<<
4
);
return
{
ctab
[
raw1
&
0xff
]
|
(
ctab
[(
raw1
>>
8
)
&
0xff
]
<<
4
)
,
ctab
[
raw2
&
0xff
]
|
(
ctab
[(
raw2
>>
8
)
&
0xff
]
<<
4
)
}
;
}
uint64_t
block2morton2D_64
(
uint64_t
v
)
{
...
...
@@ -98,13 +98,13 @@ uint64_t block2morton2D_64 (uint64_t v)
|
(
I
(
utab
[(
v
>>
32
)
&
0xff
])
<<
1
)
|
(
I
(
utab
[(
v
>>
40
)
&
0xff
])
<<
17
)
|
(
I
(
utab
[(
v
>>
48
)
&
0xff
])
<<
33
)
|
(
I
(
utab
[(
v
>>
56
)
&
0xff
])
<<
49
);
}
uint64_t
coord2morton2D_64
(
uint64_t
x
,
uint64_t
y
)
uint64_t
coord2morton2D_64
(
std
::
array
<
uint64_t
,
2
>
x
y
)
{
typedef
uint64_t
I
;
return
I
(
utab
[
x
&
0xff
])
|
(
I
(
utab
[(
x
>>
8
)
&
0xff
])
<<
16
)
|
(
I
(
utab
[(
x
>>
16
)
&
0xff
])
<<
32
)
|
(
I
(
utab
[(
x
>>
24
)
&
0xff
])
<<
48
)
|
(
I
(
utab
[
y
&
0xff
])
<<
1
)
|
(
I
(
utab
[(
y
>>
8
)
&
0xff
])
<<
17
)
|
(
I
(
utab
[(
y
>>
16
)
&
0xff
])
<<
33
)
|
(
I
(
utab
[(
y
>>
24
)
&
0xff
])
<<
49
);
return
I
(
utab
[
x
y
[
0
]
&
0xff
])
|
(
I
(
utab
[(
x
y
[
0
]
>>
8
)
&
0xff
])
<<
16
)
|
(
I
(
utab
[(
x
y
[
0
]
>>
16
)
&
0xff
])
<<
32
)
|
(
I
(
utab
[(
x
y
[
0
]
>>
24
)
&
0xff
])
<<
48
)
|
(
I
(
utab
[
xy
[
1
]
&
0xff
])
<<
1
)
|
(
I
(
utab
[(
xy
[
1
]
>>
8
)
&
0xff
])
<<
17
)
|
(
I
(
utab
[(
xy
[
1
]
>>
16
)
&
0xff
])
<<
33
)
|
(
I
(
utab
[(
xy
[
1
]
>>
24
)
&
0xff
])
<<
49
);
}
uint64_t
morton2block2D_64
(
uint64_t
v
)
{
...
...
@@ -117,16 +117,16 @@ uint64_t morton2block2D_64 (uint64_t v)
|
(
I
(
ctab
[
raw2
&
0xff
])
<<
32
)
|
(
I
(
ctab
[(
raw2
>>
8
)
&
0xff
])
<<
36
)
|
(
I
(
ctab
[(
raw2
>>
32
)
&
0xff
])
<<
48
)
|
(
I
(
ctab
[(
raw2
>>
40
)
&
0xff
])
<<
52
);
}
void
morton2coord2D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
)
std
::
array
<
uint64_t
,
2
>
morton2coord2D_64
(
uint64_t
v
)
{
typedef
uint64_t
I
;
I
raw1
=
v
&
0x5555555555555555
,
raw2
=
(
v
>>
1
)
&
0x5555555555555555
;
raw1
|=
raw1
>>
15
;
raw2
|=
raw2
>>
15
;
*
x
=
I
(
ctab
[
raw1
&
0xff
])
|
(
I
(
ctab
[(
raw1
>>
8
)
&
0xff
])
<<
4
)
|
(
I
(
ctab
[(
raw1
>>
32
)
&
0xff
])
<<
16
)
|
(
I
(
ctab
[(
raw1
>>
40
)
&
0xff
])
<<
20
)
;
*
y
=
I
(
ctab
[
raw2
&
0xff
])
|
(
I
(
ctab
[(
raw2
>>
8
)
&
0xff
])
<<
4
)
|
(
I
(
ctab
[(
raw2
>>
32
)
&
0xff
])
<<
16
)
|
(
I
(
ctab
[(
raw2
>>
40
)
&
0xff
])
<<
20
);
return
{
I
(
ctab
[
raw1
&
0xff
])
|
(
I
(
ctab
[(
raw1
>>
8
)
&
0xff
])
<<
4
)
|
(
I
(
ctab
[(
raw1
>>
32
)
&
0xff
])
<<
16
)
|
(
I
(
ctab
[(
raw1
>>
40
)
&
0xff
])
<<
20
)
,
I
(
ctab
[
raw2
&
0xff
])
|
(
I
(
ctab
[(
raw2
>>
8
)
&
0xff
])
<<
4
)
|
(
I
(
ctab
[(
raw2
>>
32
)
&
0xff
])
<<
16
)
|
(
I
(
ctab
[(
raw2
>>
40
)
&
0xff
])
<<
20
)
}
;
}
#else
...
...
@@ -225,12 +225,12 @@ uint32_t block2morton3D_32 (uint32_t v)
v3
=
(
v3
|
(
v3
>>
29
))
&
0x1fffffff
;
return
v3
|
(
spread3D_32
(
v
>>
20
)
<<
2
);
}
uint32_t
coord2morton3D_32
(
uint32_t
x
,
uint32_t
y
,
uint32_t
z
)
uint32_t
coord2morton3D_32
(
std
::
array
<
uint32_t
,
3
>
xy
z
)
{
uint32_t
v2
=
(
x
&
0x3ff
)
|
((
y
&
0x3ff
)
<<
10
);
uint32_t
v2
=
(
x
yz
[
0
]
&
0x3ff
)
|
((
xyz
[
1
]
&
0x3ff
)
<<
10
);
uint64_t
v3
=
spread3D_64
(
v2
);
v3
=
(
v3
|
(
v3
>>
29
))
&
0x1fffffff
;
return
v3
|
(
spread3D_32
(
z
&
0x3ff
)
<<
2
);
return
v3
|
(
spread3D_32
(
xyz
[
2
]
&
0x3ff
)
<<
2
);
}
uint32_t
morton2block3D_32
(
uint32_t
v
)
{
...
...
@@ -238,11 +238,11 @@ uint32_t morton2block3D_32 (uint32_t v)
|
(
compress3D_32
(
v
>>
1
)
<<
10
)
|
(
compress3D_32
(
v
>>
2
)
<<
20
);
}
void
morton2coord3D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
,
uint32_t
*
z
)
std
::
array
<
uint32_t
,
3
>
morton2coord3D_32
(
uint32_t
v
)
{
*
x
=
compress3D_32
(
v
)
;
*
y
=
compress3D_32
(
v
>>
1
)
;
*
z
=
compress3D_32
(
v
>>
2
);
return
{
compress3D_32
(
v
)
,
compress3D_32
(
v
>>
1
)
,
compress3D_32
(
v
>>
2
)
}
;
}
uint64_t
block2morton3D_64
(
uint64_t
v
)
...
...
@@ -251,11 +251,11 @@ uint64_t block2morton3D_64 (uint64_t v)
|
(
spread3D_64
(
v
>>
21
)
<<
1
)
|
(
spread3D_64
(
v
>>
42
)
<<
2
);
}
uint64_t
coord2morton3D_64
(
uint64_t
x
,
uint64_t
y
,
uint64_t
z
)
uint64_t
coord2morton3D_64
(
std
::
array
<
uint64_t
,
3
>
xy
z
)
{
return
spread3D_64
(
x
)
|
(
spread3D_64
(
y
)
<<
1
)
|
(
spread3D_64
(
z
)
<<
2
);
return
spread3D_64
(
x
yz
[
0
]
)
|
(
spread3D_64
(
xyz
[
1
]
)
<<
1
)
|
(
spread3D_64
(
xyz
[
2
]
)
<<
2
);
}
uint64_t
morton2block3D_64
(
uint64_t
v
)
{
...
...
@@ -263,11 +263,11 @@ uint64_t morton2block3D_64 (uint64_t v)
|
(
compress3D_64
(
v
>>
1
)
<<
21
)
|
(
compress3D_64
(
v
>>
2
)
<<
42
);
}
void
morton2coord3D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
,
uint64_t
*
z
)
std
::
array
<
uint64_t
,
3
>
morton2coord3D_64
(
uint64_t
v
)
{
*
x
=
compress3D_64
(
v
)
;
*
y
=
compress3D_64
(
v
>>
1
)
;
*
z
=
compress3D_64
(
v
>>
2
);
return
{
compress3D_64
(
v
)
,
compress3D_64
(
v
>>
1
)
,
compress3D_64
(
v
>>
2
)
}
;
}
#endif
...
...
mr_util/morton_utils.h
View file @
59c2ea9c
...
...
@@ -33,6 +33,7 @@
#define MRUTIL_MORTON_UTILS_H
#include <cstdint>
#include <array>
#ifdef __BMI2__
#include <x86intrin.h>
...
...
@@ -42,47 +43,48 @@ namespace mr {
#ifndef __BMI2__
uint32_t
block2morton2D_32
(
uint32_t
v
);
uint32_t
coord2morton2D_32
(
uint32_t
x
,
uint32_t
y
);
uint32_t
coord2morton2D_32
(
std
::
array
<
uint32_t
,
2
>
x
y
);
uint32_t
morton2block2D_32
(
uint32_t
v
);
void
morton2coord2D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
);
std
::
array
<
uint32_t
,
2
>
morton2coord2D_32
(
uint32_t
v
);
uint64_t
block2morton2D_64
(
uint64_t
v
);
uint64_t
coord2morton2D_64
(
uint64_t
x
,
uint64_t
y
);
uint64_t
coord2morton2D_64
(
std
::
array
<
uint64_t
,
2
>
x
y
);
uint64_t
morton2block2D_64
(
uint64_t
v
);
void
morton2coord2D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
);
std
::
array
<
uint64_t
,
2
>
morton2coord2D_64
(
uint64_t
v
);
uint32_t
block2morton3D_32
(
uint32_t
v
);
uint32_t
coord2morton3D_32
(
uint32_t
x
,
uint32_t
y
,
uint32_t
z
);
uint32_t
coord2morton3D_32
(
std
::
array
<
uint32_t
,
3
>
xy
z
);
uint32_t
morton2block3D_32
(
uint32_t
v
);
void
morton2coord3D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
,
uint32_t
*
z
);
std
::
array
<
uint32_t
,
3
>
morton2coord3D_32
(
uint32_t
v
);
uint64_t
block2morton3D_64
(
uint64_t
v
);
uint64_t
coord2morton3D_64
(
uint64_t
x
,
uint64_t
y
,
uint64_t
z
);
uint64_t
coord2morton3D_64
(
std
::
array
<
uint64_t
,
3
>
xy
z
);
uint64_t
morton2block3D_64
(
uint64_t
v
);
void
morton2coord3D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
,
uint64_t
*
z
);
std
::
array
<
uint64_t
,
3
>
morton2coord3D_64
(
uint64_t
v
);
#else
inline
uint32_t
block2morton2D_32
(
uint32_t
v
)
{
return
_pdep_u32
(
v
,
0x55555555u
)
|
_pdep_u32
(
v
>>
16
,
0xaaaaaaaau
);
}
inline
uint32_t
coord2morton2D_32
(
uint32_t
x
,
uint32_t
y
)
{
return
_pdep_u32
(
x
,
0x55555555u
)
|
_pdep_u32
(
y
,
0xaaaaaaaau
);
}
inline
uint32_t
coord2morton2D_32
(
std
::
array
<
uint32_t
,
2
>
x
y
)
{
return
_pdep_u32
(
x
y
[
0
]
,
0x55555555u
)
|
_pdep_u32
(
xy
[
1
]
,
0xaaaaaaaau
);
}
inline
uint32_t
morton2block2D_32
(
uint32_t
v
)
{
return
_pext_u32
(
v
,
0x55555555u
)
|
(
_pext_u32
(
v
,
0xaaaaaaaau
)
<<
16
);
}
inline
void
morton2coord2D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
)
{
*
x
=
_pext_u32
(
v
,
0x55555555u
)
;
*
y
=
_pext_u32
(
v
,
0xaaaaaaaau
);
}
inline
std
::
array
<
uint32_t
,
2
>
morton2coord2D_32
(
uint32_t
v
)
{
return
{
_pext_u32
(
v
,
0x55555555u
)
,
_pext_u32
(
v
,
0xaaaaaaaau
)
}
;
}
inline
uint64_t
block2morton2D_64
(
uint64_t
v
)
{
return
_pdep_u64
(
v
,
0x5555555555555555u
)
|
_pdep_u64
(
v
>>
32
,
0xaaaaaaaaaaaaaaaau
);
}
inline
uint64_t
coord2morton2D_64
(
uint64_t
x
,
uint64_t
y
)
{
return
_pdep_u64
(
x
,
0x5555555555555555u
)
|
_pdep_u64
(
y
,
0xaaaaaaaaaaaaaaaau
);
}
inline
uint64_t
coord2morton2D_64
(
std
::
array
<
uint64_t
,
2
>
xy
)
{
return
_pdep_u64
(
xy
[
0
],
0x5555555555555555u
)
|
_pdep_u64
(
xy
[
1
],
0xaaaaaaaaaaaaaaaau
);
}
inline
uint64_t
morton2block2D_64
(
uint64_t
v
)
{
return
_pext_u64
(
v
,
0x5555555555555555u
)
|
(
_pext_u64
(
v
,
0xaaaaaaaaaaaaaaaau
)
<<
32
);
}
inline
void
morton2coord2D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
)
inline
std
::
array
<
uint64_t
,
2
>
morton2coord2D_64
(
uint64_t
v
)
{
*
x
=
_pext_u64
(
v
,
0x5555555555555555u
)
;
*
y
=
_pext_u64
(
v
,
0xaaaaaaaaaaaaaaaau
);
return
{
_pext_u64
(
v
,
0x5555555555555555u
)
,
_pext_u64
(
v
,
0xaaaaaaaaaaaaaaaau
)
}
;
}
inline
uint32_t
block2morton3D_32
(
uint32_t
v
)
...
...
@@ -91,11 +93,11 @@ inline uint32_t block2morton3D_32 (uint32_t v)
|
_pdep_u32
(
v
>>
10
,
0x12492492u
)
|
_pdep_u32
(
v
>>
20
,
0x24924924u
);
}
inline
uint32_t
coord2morton3D_32
(
uint32_t
x
,
uint32_t
y
,
uint32_t
z
)
inline
uint32_t
coord2morton3D_32
(
std
::
array
<
uint32_t
,
3
>
xy
z
)
{
return
_pdep_u32
(
x
,
0x09249249u
)
|
_pdep_u32
(
y
,
0x12492492u
)
|
_pdep_u32
(
z
,
0x24924924u
);
return
_pdep_u32
(
x
yz
[
0
]
,
0x09249249u
)
|
_pdep_u32
(
xyz
[
1
]
,
0x12492492u
)
|
_pdep_u32
(
xyz
[
2
]
,
0x24924924u
);
}
inline
uint32_t
morton2block3D_32
(
uint32_t
v
)
{
...
...
@@ -103,12 +105,11 @@ inline uint32_t morton2block3D_32 (uint32_t v)
|
(
_pext_u32
(
v
,
0x12492492u
)
<<
10
)
|
(
_pext_u32
(
v
,
0x24924924u
)
<<
20
);
}
inline
void
morton2coord3D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
,
uint32_t
*
z
)
inline
std
::
array
<
uint32_t
,
3
>
morton2coord3D_32
(
uint32_t
v
)
{
*
x
=
_pext_u32
(
v
,
0x09249249u
)
;
*
y
=
_pext_u32
(
v
,
0x12492492u
)
;
*
z
=
_pext_u32
(
v
,
0x24924924u
);
return
{
_pext_u32
(
v
,
0x09249249u
)
,
_pext_u32
(
v
,
0x12492492u
)
,
_pext_u32
(
v
,
0x24924924u
)
}
;
}
inline
uint64_t
block2morton3D_64
(
uint64_t
v
)
{
...
...
@@ -116,11 +117,11 @@ inline uint64_t block2morton3D_64 (uint64_t v)
|
_pdep_u64
(
v
>>
21
,
0x2492492492492492u
)
|
_pdep_u64
(
v
>>
42
,
0x4924924924924924u
);
}
inline
uint64_t
coord2morton3D_64
(
uint64_t
x
,
uint64_t
y
,
uint64_t
z
)
inline
uint64_t
coord2morton3D_64
(
std
::
array
<
uint64_t
,
3
>
xy
z
)
{
return
_pdep_u64
(
x
,
0x1249249249249249u
)
|
_pdep_u64
(
y
,
0x2492492492492492u
)
|
_pdep_u64
(
z
,
0x4924924924924924u
);
return
_pdep_u64
(
x
yz
[
0
]
,
0x1249249249249249u
)
|
_pdep_u64
(
xyz
[
1
]
,
0x2492492492492492u
)
|
_pdep_u64
(
xyz
[
2
]
,
0x4924924924924924u
);
}
inline
uint64_t
morton2block3D_64
(
uint64_t
v
)
{
...
...
@@ -128,12 +129,11 @@ inline uint64_t morton2block3D_64 (uint64_t v)
|
(
_pext_u64
(
v
,
0x2492492492492492u
)
<<
21
)
|
(
_pext_u64
(
v
,
0x4924924924924924u
)
<<
42
);
}
inline
void
morton2coord3D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
,
uint64_t
*
z
)
inline
std
::
array
<
uint64_t
,
3
>
morton2coord3D_64
(
uint64_t
v
)
{
*
x
=
_pext_u64
(
v
,
0x1249249249249249u
)
;
*
y
=
_pext_u64
(
v
,
0x2492492492492492u
)
;
*
z
=
_pext_u64
(
v
,
0x4924924924924924u
);
return
{
_pext_u64
(
v
,
0x1249249249249249u
)
,
_pext_u64
(
v
,
0x2492492492492492u
)
,
_pext_u64
(
v
,
0x4924924924924924u
)
}
;
}
#endif
...
...
@@ -149,25 +149,23 @@ uint32_t peano2morton3D_32(uint32_t v, int bits);
uint64_t
morton2peano3D_64
(
uint64_t
v
,
int
bits
);
uint64_t
peano2morton3D_64
(
uint64_t
v
,
int
bits
);
inline
uint32_t
coord2block2D_32
(
uint32_t
x
,
uint32_t
y
)
{
return
(
x
&
0xffff
)
|
(
y
<<
16
);
}
inline
void
block2coord2D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
)
{
*
x
=
v
&
0xffff
;
*
y
=
v
>>
16
;
}
inline
uint32_t
coord2block3D_32
(
uint32_t
x
,
uint32_t
y
,
uint32_t
z
)
{
return
(
x
&
0x3ff
)
|
((
y
&
0x3ff
)
<<
10
)
|
((
z
&
0x3ff
)
<<
20
);
}
inline
void
block2coord3D_32
(
uint32_t
v
,
uint32_t
*
x
,
uint32_t
*
y
,
uint32_t
*
z
)
{
*
x
=
v
&
0x3ff
;
*
y
=
(
v
>>
10
)
&
0x3ff
;
*
z
=
(
v
>>
20
)
&
0x3ff
;
}
inline
uint64_t
coord2block2D_64
(
uint64_t
x
,
uint64_t
y
)
{
return
(
x
&
0xffffffff
)
|
(
y
<<
32
);
}
inline
void
block2coord2D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
)
{
*
x
=
v
&
0xffffffff
;
*
y
=
v
>>
32
;
}
inline
uint64_t
coord2block3D_64
(
uint64_t
x
,
uint64_t
y
,
uint64_t
z
)
{
return
(
x
&
0x1fffff
)
|
((
y
&
0x1fffff
)
<<
21
)
|
((
z
&
0x1fffff
)
<<
42
);
}
inline
void
block2coord3D_64
(
uint64_t
v
,
uint64_t
*
x
,
uint64_t
*
y
,
uint64_t
*
z
)
{
*
x
=
v
&
0x1fffff
;
*
y
=
(
v
>>
21
)
&
0x1fffff
;
*
z
=
(
v
>>
42
)
&
0x1fffff
;
}
inline
uint32_t
coord2block2D_32
(
std
::
array
<
uint32_t
,
2
>
xy
)
{
return
(
xy
[
0
]
&
0xffff
)
|
(
xy
[
1
]
<<
16
);
}
inline
std
::
array
<
uint32_t
,
2
>
block2coord2D_32
(
uint32_t
v
)
{
return
{
v
&
0xffff
,
v
>>
16
};
}
inline
uint32_t
coord2block3D_32
(
std
::
array
<
uint32_t
,
3
>
xyz
)
{
return
(
xyz
[
0
]
&
0x3ff
)
|
((
xyz
[
1
]
&
0x3ff
)
<<
10
)
|
((
xyz
[
2
]
&
0x3ff
)
<<
20
);
}
inline
std
::
array
<
uint32_t
,
3
>
block2coord3D_32
(
uint32_t
v
)
{
return
{
v
&
0x3ff
,
(
v
>>
10
)
&
0x3ff
,
(
v
>>
20
)
&
0x3ff
};
}
inline
uint64_t
coord2block2D_64
(
std
::
array
<
uint64_t
,
2
>
xy
)
{
return
(
xy
[
0
]
&
0xffffffff
)
|
(
xy
[
1
]
<<
32
);
}
inline
std
::
array
<
uint64_t
,
2
>
block2coord2D_64
(
uint64_t
v
)
{
return
{
v
&
0xffffffff
,
v
>>
32
};
}
inline
uint64_t
coord2block3D_64
(
std
::
array
<
uint64_t
,
3
>
xyz
)
{
return
(
xyz
[
0
]
&
0x1fffff
)
|
((
xyz
[
1
]
&
0x1fffff
)
<<
21
)
|
((
xyz
[
2
]
&
0x1fffff
)
<<
42
);
}
inline
std
::
array
<
uint64_t
,
3
>
block2coord3D_64
(
uint64_t
v
)
{
return
{
v
&
0x1fffff
,
(
v
>>
21
)
&
0x1fffff
,
(
v
>>
42
)
&
0x1fffff
};
}
}
...
...
test/morton_test.cc
0 → 100644
View file @
59c2ea9c
#include <functional>
#include "mr_util/morton_utils.h"
#include "mr_util/error_handling.h"
using
namespace
std
;
using
namespace
mr
;
namespace
{
int64_t
t00
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
x
=
0
;
x
<
0x400
;
++
x
)
for
(
uint32_t
y
=
0
;
y
<
0x400
;
++
y
)
for
(
uint32_t
z
=
0
;
z
<
0x400
;
++
z
)
{
++
cnt
;
auto
res
=
morton2coord3D_32
(
coord2morton3D_32
({
x
,
y
,
z
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
&&
res
[
2
]
==
z
,
"bug"
);
}
return
cnt
;
}
int64_t
t01
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
x
=
0
;
x
<
0x400
;
++
x
)
for
(
uint32_t
y
=
0
;
y
<
0x400
;
++
y
)
for
(
uint32_t
z
=
0
;
z
<
0x400
;
++
z
)
{
++
cnt
;
auto
res
=
block2coord3D_32
(
coord2block3D_32
({
x
,
y
,
z
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
&&
res
[
2
]
==
z
,
"bug"
);
}
return
cnt
;
}
int64_t
t02
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
v
=
0
;
v
<
0x40000000
;
v
+=
15
,
++
cnt
)
MR_assert
(
v
==
peano2morton3D_32
(
morton2peano3D_32
(
v
,
10
),
10
),
"bug"
);
return
cnt
;
}
int64_t
t03
()
{
for
(
uint32_t
v
=
0
;
v
<
0x40000000
;
++
v
)
MR_assert
(
v
==
block2morton3D_32
(
morton2block3D_32
(
v
)),
"bug"
);
return
0x40000000
;
}
int64_t
t04
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
v
=
0
;
v
<
0xffffffe0
;
v
+=
15
,
++
cnt
)
MR_assert
(
v
==
peano2morton2D_32
(
morton2peano2D_32
(
v
,
16
),
16
),
"bug"
);
return
cnt
;
}
int64_t
t10
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
x
=
0
;
x
<
0x10000
;
++
x
)
for
(
uint32_t
y
=
0
;
y
<
0x10000
;
++
y
)
{
++
cnt
;
auto
res
=
morton2coord2D_32
(
coord2morton2D_32
({
x
,
y
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
,
"bug"
);
}
return
cnt
;
}
int64_t
t11
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
x
=
0
;
x
<
0x10000
;
++
x
)
for
(
uint32_t
y
=
0
;
y
<
0x10000
;
++
y
)
{
++
cnt
;
auto
res
=
block2coord2D_32
(
coord2block2D_32
({
x
,
y
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
,
"bug"
);
}
return
cnt
;
}
int64_t
t12
()
{
uint32_t
v
=
0
;
do
MR_assert
(
v
==
block2morton2D_32
(
morton2block2D_32
(
v
)),
"bug"
);
while
(
++
v
!=
0
);
return
0x100000000
;
}
int64_t
t20
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
x
=
0
;
x
<
0xffff0000
;
x
+=
0xfff5
)
for
(
uint64_t
y
=
0
;
y
<
0xffff0000
;
y
+=
0xfff7
)
{
++
cnt
;
auto
res
=
morton2coord2D_64
(
coord2morton2D_64
({
x
,
y
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
,
"bug"
);
}
return
cnt
;
}
int64_t
t21
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
x
=
0
;
x
<
0xffff0000
;
x
+=
0xfff5
)
for
(
uint64_t
y
=
0
;
y
<
0xffff0000
;
y
+=
0xfff7
)
{
++
cnt
;
auto
res
=
block2coord2D_64
(
coord2block2D_64
({
x
,
y
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
,
"bug"
);
}
return
cnt
;
}
int64_t
t22
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
v
=
0
;
v
<
0xffffffff00000000
;
v
+=
0xfffff563
,
++
cnt
)
MR_assert
(
v
==
block2morton2D_64
(
morton2block2D_64
(
v
)),
"bug"
);
return
cnt
;
}
int64_t
t30
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
x
=
0
;
x
<
0x200000
;
x
+=
0xff34
)
for
(
uint64_t
y
=
0
;
y
<
0x200000
;
y
+=
0xff84
)
for
(
uint64_t
z
=
0
;
z
<
0x200000
;
z
+=
0xff96
)
{
++
cnt
;
auto
res
=
morton2coord3D_64
(
coord2morton3D_64
({
x
,
y
,
z
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
&&
res
[
2
]
==
z
,
"bug"
);
}
return
cnt
;
}
int64_t
t31
()
{
int64_t
cnt
=
0
;
for
(
uint32_t
x
=
0
;
x
<
0x400
;
++
x
)
for
(
uint32_t
y
=
0
;
y
<
0x400
;
++
y
)
for
(
uint32_t
z
=
0
;
z
<
0x400
;
++
z
)
{
++
cnt
;
auto
res
=
block2coord3D_32
(
coord2block3D_32
({
x
,
y
,
z
}));
MR_assert
(
res
[
0
]
==
x
&&
res
[
1
]
==
y
&&
res
[
2
]
==
z
,
"bug"
);
}
return
cnt
;
}
int64_t
t32
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
v
=
0
;
v
<
0x7fffffff00000000
;
v
+=
0xfffffff78
,
++
cnt
)
MR_assert
(
v
==
peano2morton3D_64
(
morton2peano3D_64
(
v
,
21
),
21
),
"bug"
);
return
cnt
;
}
int64_t
t33
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
v
=
0
;
v
<
0x7fffffff00000000
;
v
+=
0xffffff78
,
++
cnt
)
MR_assert
(
v
==
block2morton3D_64
(
morton2block3D_64
(
v
)),
"bug"
);
return
cnt
;
}
int64_t
t34
()
{
int64_t
cnt
=
0
;
for
(
uint64_t
v
=
0
;
v
<
0xffffffff00000000
;
v
+=
0xfffffff78
,
++
cnt
)
MR_assert
(
v
==
peano2morton2D_64
(
morton2peano2D_64
(
v
,
32
),
32
),
"bug"
);
return
cnt
;
}
}
// unnamed namespace
#include <cstdio>
#include "mr_util/timers.h"
using
namespace
std
;
void
runtest
(
function
<
int64_t
()
>
tf
,
const
char
*
tn
)
{
SimpleTimer
t
;
auto
res
=
tf
();
printf
(
"%s OK. MOps/s: %7.2f
\n
"
,
tn
,
2e-6
*
res
/
t
());
}
int
main
(
int
argc
,
const
char
**
argv
)
{
MR_assert
((
argc
==
1
)
||
(
argv
[
0
]
==
nullptr
),
"problem with args"
);
runtest
(
t10
,
"coord <-> Morton 2D 32bit"
);
runtest
(
t11
,
"coord <-> Block 2D 32bit"
);
runtest
(
t12
,
"Morton <-> Block 2D 32bit"
);
runtest
(
t04
,
"Morton <-> Peano 2D 32bit"
);
runtest
(
t20
,
"coord <-> Morton 2D 64bit"
);
runtest
(
t21
,
"coord <-> Block 2D 64bit"
);
runtest
(
t22
,
"Morton <-> Block 2D 64bit"
);
runtest
(
t34
,
"Morton <-> Peano 2D 64bit"
);
runtest
(
t00
,
"coord <-> Morton 3D 32bit"
);
runtest
(
t01
,
"coord <-> Block 3D 32bit"
);
runtest
(
t02
,
"Morton <-> Peano 3D 32bit"
);
runtest
(
t03
,
"Morton <-> Block 3D 32bit"
);
runtest
(
t30
,
"coord <-> Morton 3D 64bit"
);
runtest
(
t31
,
"coord <-> Block 3D 64bit"
);
runtest
(
t32
,
"Morton <-> Peano 3D 64bit"
);
runtest
(
t33
,
"Morton <-> Block 3D 64bit"
);
}
Write
Preview
Markdown
is supported
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