Skip to content

Commit

Permalink
Use __cplusplus version check, and minor improve on the bitmask. (#239)
Browse files Browse the repository at this point in the history
* use __cplusplus version checking instead of feature macros

* use bit operations for count_true

* add lib implementation test

* clang-format

* minor

---------

Co-authored-by: Samuel Li <shaomeng@cisl-vapor>
Co-authored-by: Samuel Li <Sam@Navada>
  • Loading branch information
3 people authored Apr 30, 2024
1 parent ddb02cd commit fe9df24
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 29 deletions.
2 changes: 1 addition & 1 deletion include/Bitmask.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Bitmask {
auto view_buffer() const -> const std::vector<uint64_t>&;
void use_bitstream(const void* p);

#if defined __cpp_lib_three_way_comparison && defined __cpp_impl_three_way_comparison
#if __cplusplus >= 201907L && defined __cpp_lib_three_way_comparison
auto operator<=>(const Bitmask& rhs) const noexcept;
auto operator==(const Bitmask& rhs) const noexcept -> bool;
#endif
Expand Down
27 changes: 21 additions & 6 deletions src/Bitmask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <cassert>
#include <limits>

#if __cplusplus >= 201907L
#include <bit>
#endif

sperr::Bitmask::Bitmask(size_t nbits)
{
if (nbits > 0) {
Expand Down Expand Up @@ -48,11 +52,13 @@ auto sperr::Bitmask::has_true(size_t start, size_t len) const -> int64_t
{
auto long_idx = start / 64;
auto processed_bits = int64_t{0};

// Collect the remaining bits from the start long.
auto word = m_buf[long_idx];
auto answer = uint64_t{0};
for (auto i = start - long_idx * 64; i < 64 && processed_bits < len; i++) {

// Collect the remaining bits from the start long.
auto begin_idx = start - long_idx * 64;
auto nbits = std::min(size_t{64}, begin_idx + len);
for (auto i = begin_idx; i < nbits; i++) {
answer |= word & (uint64_t{1} << i);
if constexpr (Position) {
if (answer != 0)
Expand All @@ -70,9 +76,14 @@ auto sperr::Bitmask::has_true(size_t start, size_t len) const -> int64_t
word = m_buf[++long_idx];
if (word) {
if constexpr (Position) {
#if __cplusplus >= 201907L
int64_t i = std::countr_zero(word);
return processed_bits + i;
#else
for (int64_t i = 0; i < 64; i++)
if (word & (uint64_t{1} << i))
return processed_bits + i;
#endif
}
else
return 1;
Expand All @@ -82,7 +93,7 @@ auto sperr::Bitmask::has_true(size_t start, size_t len) const -> int64_t

// Examine the remaining bits
if (processed_bits < len) {
auto nbits = len - processed_bits;
nbits = len - processed_bits;
assert(nbits < 64);
word = m_buf[++long_idx];
answer = 0;
Expand Down Expand Up @@ -112,11 +123,15 @@ auto sperr::Bitmask::count_true() const -> size_t

// Note that unused bits in the last long are not guaranteed to be all 0's.
for (size_t i = 0; i < m_buf.size() - 1; i++) {
const auto val = m_buf[i];
auto val = m_buf[i];
#if __cplusplus >= 201907L
counter += std::popcount(val);
#else
if (val != 0) {
for (size_t j = 0; j < 64; j++)
counter += ((val >> j) & uint64_t{1});
}
#endif
}
const auto val = m_buf.back();
if (val != 0) {
Expand Down Expand Up @@ -186,7 +201,7 @@ void sperr::Bitmask::use_bitstream(const void* p)
std::copy(pu64, pu64 + m_buf.size(), m_buf.begin());
}

#if defined __cpp_lib_three_way_comparison && defined __cpp_impl_three_way_comparison
#if __cplusplus >= 201907L && defined __cpp_lib_three_way_comparison
auto sperr::Bitmask::operator<=>(const Bitmask& rhs) const noexcept
{
auto cmp = m_num_bits <=> rhs.m_num_bits;
Expand Down
5 changes: 2 additions & 3 deletions src/SPECK1D_INT_DEC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <cstring> // std::memcpy()
#include <numeric>

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
#include <bit>
#endif

Expand All @@ -19,11 +19,10 @@ void sperr::SPECK1D_INT_DEC<T>::m_sorting_pass()
for (size_t i = 0; i < bits_x64; i += 64) {
auto value = m_LIP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
size_t j = std::countr_zero(value);
m_process_P(i + j, j, true);

value &= value - 1;
}
#else
Expand Down
5 changes: 2 additions & 3 deletions src/SPECK1D_INT_ENC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <cstring> // std::memcpy()
#include <numeric>

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
#include <bit>
#endif

Expand All @@ -19,11 +19,10 @@ void sperr::SPECK1D_INT_ENC<T>::m_sorting_pass()
for (size_t i = 0; i < bits_x64; i += 64) {
auto value = m_LIP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
size_t j = std::countr_zero(value);
m_process_P(i + j, SigType::Dunno, j, true);

value &= value - 1;
}
#else
Expand Down
5 changes: 2 additions & 3 deletions src/SPECK2D_INT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <algorithm>
#include <cassert>

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
#include <bit>
#endif

Expand All @@ -17,11 +17,10 @@ void sperr::SPECK2D_INT<T>::m_sorting_pass()
for (size_t i = 0; i < bits_x64; i += 64) {
auto value = m_LIP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
size_t j = std::countr_zero(value);
m_process_P(i + j, j, true);

value &= value - 1;
}
#else
Expand Down
5 changes: 2 additions & 3 deletions src/SPECK3D_INT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <cstring>
#include <numeric>

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
#include <bit>
#endif

Expand Down Expand Up @@ -106,11 +106,10 @@ void sperr::SPECK3D_INT<T>::m_sorting_pass()
for (size_t i = 0; i < bits_x64; i += 64) {
auto value = m_LIP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
auto j = std::countr_zero(value);
m_process_P_lite(i + j);

value &= value - 1;
}
#else
Expand Down
11 changes: 4 additions & 7 deletions src/SPECK_INT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <cstring>
#include <numeric>

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
#include <bit>
#endif

Expand Down Expand Up @@ -317,13 +317,12 @@ void sperr::SPECK_INT<T>::m_refinement_pass_encode()
for (size_t i = 0; i < bits_x64; i += 64) { // Evaluate 64 bits at a time.
auto value = m_LSP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
auto j = std::countr_zero(value);
const bool o1 = m_coeff_buf[i + j] >= m_threshold;
m_coeff_buf[i + j] -= tmp1[o1];
m_bit_buffer.wbit(o1);

value &= value - 1;
}
#else
Expand Down Expand Up @@ -375,7 +374,7 @@ void sperr::SPECK_INT<T>::m_refinement_pass_decode()
for (size_t i = 0; i < bits_x64; i += 64) { // <-- Point 2
auto value = m_LSP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
auto j = std::countr_zero(value);
if (m_bit_buffer.rbit())
Expand All @@ -384,7 +383,6 @@ void sperr::SPECK_INT<T>::m_refinement_pass_decode()
m_coeff_buf[i + j] -= half_t;
if (++read_pos == m_avail_bits) // <-- Point 3
goto INITIALIZE_NEWLY_FOUND_POINTS_LABEL; // <-- Point 4

value &= value - 1;
}
#else
Expand Down Expand Up @@ -417,14 +415,13 @@ void sperr::SPECK_INT<T>::m_refinement_pass_decode()
for (size_t i = 0; i < bits_x64; i += 64) {
auto value = m_LSP_mask.rlong(i);

#if defined __cpp_lib_bitops
#if __cplusplus >= 201907L
while (value) {
auto j = std::countr_zero(value);
if (m_bit_buffer.rbit())
++(m_coeff_buf[i + j]);
if (++read_pos == m_avail_bits)
goto INITIALIZE_NEWLY_FOUND_POINTS_LABEL;

value &= value - 1;
}
#else
Expand Down
6 changes: 3 additions & 3 deletions test_scripts/bitstream_unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ TEST(Bitmask, BufferTransfer)

TEST(Bitmask, has_true)
{
const size_t mask_size = 130;
const size_t mask_size = 210;

// Loop over all positions
for (size_t idx = 0; idx < mask_size; idx++) {
Expand Down Expand Up @@ -390,7 +390,7 @@ TEST(Bitmask, has_true)

TEST(Bitmask, has_true_position)
{
const size_t mask_size = 130;
const size_t mask_size = 210;

// Loop over all positions
for (size_t idx = 0; idx < mask_size; idx++) {
Expand Down Expand Up @@ -421,7 +421,7 @@ TEST(Bitmask, has_true_position)
{}
}

#if defined __cpp_lib_three_way_comparison && defined __cpp_impl_three_way_comparison
#if __cplusplus >= 201907L && defined __cpp_lib_three_way_comparison
TEST(Bitmask, spaceship)
{
auto src = Mask(60);
Expand Down

0 comments on commit fe9df24

Please sign in to comment.