Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions cpp/src/parquet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,7 @@ append_runtime_avx2_src(PARQUET_SRCS level_comparison_simd_256.cc)

if(ARROW_HAVE_RUNTIME_AVX2)
# AVX2 is used as a proxy for BMI2.
list(APPEND
PARQUET_SRCS
level_comparison_avx2.cc
level_conversion_bmi2.cc
bloom_filter_avx2.cc)
list(APPEND PARQUET_SRCS level_conversion_bmi2.cc bloom_filter_avx2.cc)
# We need CMAKE_CXX_FLAGS_RELEASE here to prevent the one-definition-rule
# violation with -DCMAKE_BUILD_TYPE=MinSizeRel. CMAKE_CXX_FLAGS_RELEASE
# will force inlining as much as possible.
Expand All @@ -218,8 +214,8 @@ if(ARROW_HAVE_RUNTIME_AVX2)
separate_arguments(RELEASE_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_RELEASE}")
list(APPEND AVX2_FLAGS ${RELEASE_FLAGS})
endif()
set_source_files_properties(level_comparison_avx2.cc bloom_filter_avx2.cc
PROPERTIES COMPILE_OPTIONS "${AVX2_FLAGS}")
set_source_files_properties(bloom_filter_avx2.cc PROPERTIES COMPILE_OPTIONS
"${AVX2_FLAGS}")
# WARNING: DO NOT BLINDLY COPY THIS CODE FOR OTHER BMI2 USE CASES.
# This code is always guarded by runtime dispatch which verifies
# BMI2 is present. For a very small number of CPUs AVX2 does not
Expand Down
7 changes: 2 additions & 5 deletions cpp/src/parquet/level_comparison.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@
#include <array>

#include "parquet/level_comparison.h"

#if defined(ARROW_HAVE_RUNTIME_AVX2)
# include "parquet/level_comparison_avx2_internal.h"
#endif

#include "parquet/level_comparison_simd_internal.h"

#define PARQUET_IMPL_NAMESPACE standard
Expand All @@ -45,6 +40,8 @@ struct GreaterThanDynamicFunction {
static constexpr auto targets() {
return std::array{
ARROW_DISPATCH_TARGET_NONE(&standard::GreaterThanBitmapImpl) //
ARROW_DISPATCH_TARGET_NEON(&GreaterThanBitmapNeon) //
ARROW_DISPATCH_TARGET_SSE4_2(&GreaterThanBitmapSse42) //
ARROW_DISPATCH_TARGET_AVX2(&GreaterThanBitmapAvx2) //
};
}
Expand Down
32 changes: 0 additions & 32 deletions cpp/src/parquet/level_comparison_avx2.cc

This file was deleted.

28 changes: 0 additions & 28 deletions cpp/src/parquet/level_comparison_avx2_internal.h

This file was deleted.

8 changes: 8 additions & 0 deletions cpp/src/parquet/level_comparison_simd_128.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

#if defined(ARROW_HAVE_NEON)
# define FIND_MIN_MAX_PLATFORM FindMinMaxNeon
# define GREATER_THAN_BITMAP_PLATFORM GreaterThanBitmapNeon
# define ARCH_PLATFORM xsimd::neon64
#elif defined(ARROW_HAVE_SSE4_2) || defined(ARROW_HAVE_RUNTIME_SSE4_2)
# define FIND_MIN_MAX_PLATFORM FindMinMaxSse42
# define GREATER_THAN_BITMAP_PLATFORM GreaterThanBitmapSse42
# define ARCH_PLATFORM xsimd::sse4_2
#endif

Expand All @@ -34,8 +36,14 @@ MinMax FIND_MIN_MAX_PLATFORM(const int16_t* levels, int64_t num_levels) {
return FindMinMaxSimd<ARCH_PLATFORM>(levels, num_levels);
}

uint64_t GREATER_THAN_BITMAP_PLATFORM(const int16_t* levels, int64_t num_levels,
int16_t rhs) {
return GreaterThanBitmapSimd<ARCH_PLATFORM>(levels, num_levels, rhs);
}

} // namespace parquet::internal

# undef ARCH_PLATFORM
# undef GREATER_THAN_BITMAP_PLATFORM
# undef FIND_MIN_MAX_PLATFORM
#endif // FIND_MIN_MAX_PLATFORM
7 changes: 7 additions & 0 deletions cpp/src/parquet/level_comparison_simd_256.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#if defined(ARROW_HAVE_RUNTIME_AVX2)
# define FIND_MIN_MAX_PLATFORM FindMinMaxAvx2
# define GREATER_THAN_BITMAP_PLATFORM GreaterThanBitmapAvx2
# define ARCH_PLATFORM xsimd::avx2
#endif

Expand All @@ -33,7 +34,13 @@ MinMax FIND_MIN_MAX_PLATFORM(const int16_t* levels, int64_t num_levels) {
return FindMinMaxSimd<ARCH_PLATFORM>(levels, num_levels);
}

uint64_t GREATER_THAN_BITMAP_PLATFORM(const int16_t* levels, int64_t num_levels,
int16_t rhs) {
return GreaterThanBitmapSimd<ARCH_PLATFORM>(levels, num_levels, rhs);
}

} // namespace parquet::internal

#undef ARCH_PLATFORM
#undef GREATER_THAN_BITMAP_PLATFORM
#undef FIND_MIN_MAX_PLATFORM
3 changes: 3 additions & 0 deletions cpp/src/parquet/level_comparison_simd_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ namespace parquet::internal {

#if defined(ARROW_HAVE_NEON)
MinMax FindMinMaxNeon(const int16_t* levels, int64_t num_levels);
uint64_t GreaterThanBitmapNeon(const int16_t* levels, int64_t num_levels, int16_t rhs);
#endif

#if defined(ARROW_HAVE_SSE4_2) || defined(ARROW_HAVE_RUNTIME_SSE4_2)
MinMax FindMinMaxSse42(const int16_t* levels, int64_t num_levels);
uint64_t GreaterThanBitmapSse42(const int16_t* levels, int64_t num_levels, int16_t rhs);
#endif

#if defined(ARROW_HAVE_RUNTIME_AVX2)
MinMax FindMinMaxAvx2(const int16_t* levels, int64_t num_levels);
uint64_t GreaterThanBitmapAvx2(const int16_t* levels, int64_t num_levels, int16_t rhs);
#endif

} // namespace parquet::internal
23 changes: 23 additions & 0 deletions cpp/src/parquet/level_comparison_simd_kernel_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <cstdint>
#include <limits>

#include "arrow/util/endian.h"
#include "parquet/level_comparison.h"

namespace parquet::internal {
Expand Down Expand Up @@ -53,4 +54,26 @@ MinMax FindMinMaxSimd(const int16_t* levels, int64_t num_levels) {
return out;
}

/// Build a bitmap (LSB first, little-endian) with bit i set iff levels[i] > rhs.
///
/// \param[in] num_levels must be in [0, 64].
template <typename Arch>
uint64_t GreaterThanBitmapSimd(const int16_t* levels, int64_t num_levels, int16_t rhs) {
using batch = xsimd::batch<int16_t, Arch>;
constexpr int64_t kLanes = static_cast<int64_t>(batch::size);
static_assert(kLanes <= 64);

const batch vrhs(rhs);
uint64_t mask = 0;
int64_t i = 0;
for (; i + kLanes <= num_levels; i += kLanes) {
const auto gt = batch::load_unaligned(levels + i) > vrhs;
mask |= static_cast<uint64_t>(gt.mask()) << i;
}
for (; i < num_levels; ++i) {
mask |= static_cast<uint64_t>(levels[i] > rhs) << i;
}
return ::arrow::bit_util::ToLittleEndian(mask);
}

} // namespace parquet::internal
Loading