-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b0e80e3
commit a328636
Showing
25 changed files
with
1,438 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#include <cstdint> | ||
#include <cstddef> | ||
|
||
|
||
#include <arcticdb/codec/fastlanes_common.hpp> | ||
#include <arcticdb/log/log.hpp> | ||
|
||
namespace arcticdb { | ||
|
||
|
||
template<typename T, size_t bit_width> | ||
constexpr T construct_mask() { | ||
if constexpr (bit_width == type_bits<T>()) | ||
return T(-1); | ||
else | ||
return (T(1) << bit_width) - 1; | ||
} | ||
|
||
template<typename T, size_t width> | ||
struct BitPackHelper { | ||
static constexpr size_t bit_width = width; | ||
static constexpr size_t num_bits = Helper<T>::num_bits; | ||
static constexpr size_t num_lanes = Helper<T>::num_lanes; | ||
static_assert(bit_width <= num_bits); | ||
|
||
static constexpr T mask = construct_mask<T, bit_width>(); | ||
|
||
static constexpr size_t remaining_bits(size_t row) { | ||
return ((row + 1) * bit_width) % num_bits; | ||
}; | ||
|
||
static constexpr size_t current_bits(size_t row) { | ||
return bit_width - remaining_bits(row); | ||
} | ||
|
||
static constexpr size_t current_word (size_t row) { | ||
return (row * bit_width) / num_bits; | ||
} | ||
|
||
static constexpr size_t next_word (size_t row) { | ||
return ((row + 1) * bit_width) / num_bits; | ||
} | ||
|
||
static constexpr bool at_end(size_t row) { | ||
return next_word(row) > current_word(row); | ||
} | ||
|
||
static constexpr size_t shift(size_t row) { | ||
return (row * bit_width) % num_bits; | ||
} | ||
}; | ||
|
||
static_assert(BitPackHelper<uint8_t, 3>::mask == 7); | ||
static_assert(BitPackHelper<uint8_t, 3>::at_end(2)); | ||
static_assert(!BitPackHelper<uint8_t, 3>::at_end(3)); | ||
|
||
template<typename T, typename p, size_t bit_width, typename Kernel> | ||
void bitpack_lane( | ||
const size_t lane, | ||
const T* __restrict in, | ||
T* __restrict out, | ||
Kernel& kernel) { | ||
static constexpr auto num_bits = p::num_bits; | ||
static constexpr auto num_lanes = p::num_lanes; | ||
static constexpr auto mask = p::mask; | ||
|
||
T tmp = 0; | ||
loop<T, num_bits>([lane, in, out, &tmp, &kernel](auto r) { | ||
constexpr size_t row = r; | ||
size_t idx = index(row, lane); | ||
T src = kernel(in[idx]); | ||
src &= mask; | ||
|
||
if constexpr(row == 0) { | ||
tmp = src; | ||
} else { | ||
tmp |= src << ((row * bit_width) & (num_bits - 1)); | ||
} | ||
|
||
if constexpr(p::at_end(row)) { | ||
constexpr auto current_word = p::current_word(row); | ||
constexpr auto remaining_bits = p::remaining_bits(row); | ||
out[num_lanes * current_word + lane] = tmp; | ||
//log::version().info("Writing to index {}", num_bits * current_word + lane); | ||
tmp = src >> (bit_width - remaining_bits); | ||
} | ||
}); | ||
} | ||
|
||
template<typename T, size_t bit_width> | ||
struct BitPackFused : public BitPackHelper<T, bit_width> { | ||
using Parent = BitPackHelper<T, bit_width>; | ||
static constexpr auto num_lanes = Parent::num_lanes; | ||
|
||
template <typename Kernel> | ||
static void go(const T *__restrict in, T *__restrict out, Kernel &&kernel) { | ||
for(auto lane = 0UL; lane < num_lanes; ++lane) { | ||
bitpack_lane<T, Parent, bit_width, Kernel>(lane, in, out, kernel); | ||
}; | ||
} | ||
}; | ||
|
||
template <typename T, typename Parent, size_t bit_width, typename Kernel> | ||
void bitunpack_lane( | ||
size_t lane, | ||
const T *__restrict in, | ||
T *__restrict out, | ||
Kernel &kernel) { | ||
static constexpr auto num_bits = Parent::num_bits; | ||
static constexpr auto num_lanes = Parent::num_lanes; | ||
static constexpr auto mask = Parent::mask; | ||
using p = Parent; | ||
|
||
T src = in[lane]; | ||
T tmp; | ||
loop<T, num_bits>([lane, in, out, &tmp, &kernel, &src](auto row) { | ||
constexpr auto shift = p::shift(row); | ||
if constexpr (p::at_end(row)) { | ||
constexpr auto current_bits = p::current_bits(row); | ||
constexpr auto current_bits_mask = construct_mask<T, current_bits>(); | ||
tmp = (src >> shift) & current_bits_mask; | ||
if constexpr (p::next_word(row) < bit_width) { | ||
constexpr auto next_word = p::next_word(row); | ||
constexpr auto remaining_bits_mask = construct_mask<T, p::remaining_bits(row)>(); | ||
src = in[num_lanes * next_word + lane]; | ||
tmp |= (src & remaining_bits_mask) << current_bits; | ||
} | ||
} else { | ||
tmp = (src >> shift) & mask; | ||
} | ||
|
||
size_t idx = index(row, lane); | ||
out[idx] = kernel(tmp); | ||
}); | ||
} | ||
|
||
template<typename T, size_t bit_width> | ||
struct BitUnpackFused : public BitPackHelper<T, bit_width> { | ||
using Parent = BitPackHelper<T, bit_width>; | ||
static constexpr auto num_lanes = Parent::num_lanes; | ||
|
||
template<typename Kernel> | ||
static void go(const T *__restrict in, T *__restrict out, Kernel &&kernel) { | ||
for(auto lane = 0UL; lane < num_lanes; ++lane) { | ||
bitunpack_lane<T, Parent, bit_width, Kernel>(lane, in, out, kernel); | ||
} | ||
} | ||
}; | ||
|
||
} // namespace arcticdb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#pragma once | ||
|
||
#include <arcticdb/log/log.hpp> | ||
#include <arcticdb/util/preconditions.hpp> | ||
|
||
#include <cstdint> | ||
|
||
namespace arcticdb { | ||
template<typename T> | ||
struct ConstantEncoding { | ||
|
||
#pragma pack(push, 1) | ||
struct Data { | ||
uint64_t size_; | ||
T value_; | ||
}; | ||
#pragma pack(pop) | ||
|
||
std::optional<size_t> max_required_bytes(const T* data_in, size_t num_rows) { | ||
if (num_rows == 0) | ||
return 0; | ||
|
||
const auto *pos = data_in; | ||
const auto *end = pos + num_rows; | ||
T first = *pos; | ||
++pos; | ||
do { | ||
if (*pos != first) | ||
return std::nullopt; | ||
|
||
++pos; | ||
} while (pos != end); | ||
|
||
return sizeof(Data); | ||
} | ||
|
||
size_t encode(const T *data_in, size_t num_rows, uint8_t *data_out) { | ||
if (num_rows == 0) | ||
return 0; | ||
|
||
auto *state = reinterpret_cast<Data*>(data_out); | ||
state->size_ = num_rows; | ||
state->value_ = *data_in; | ||
return sizeof(Data); | ||
} | ||
|
||
size_t decode(const uint8_t *data_in, size_t bytes, T *data_out) { | ||
util::check(bytes == sizeof(Data), "Not enough bytes in constant encoding"); | ||
|
||
const auto *state = reinterpret_cast<const Data*>(data_in); | ||
auto *target = data_out; | ||
auto *target_end = target + state->size_; | ||
std::fill(target, target_end, state->value_); | ||
return state->size_; | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* Copyright 2023 Man Group Operations Limited | ||
* | ||
* Use of this software is governed by the Business Source License 1.1 included in the file licenses/BSL.txt. | ||
* | ||
* As of the Change Date specified in that file, in accordance with the Business Source License, use of this software will be governed by the Apache License, version 2.0. | ||
*/ | ||
|
||
#include <cstdint> | ||
#include <cstddef> | ||
#include <limits> | ||
|
||
#include <arcticdb/codec/fastlanes_common.hpp> | ||
|
||
namespace arcticdb { | ||
|
||
template <typename T> | ||
void rsum(const uint8_t *__restrict a_in_p, uint8_t* __restrict a_out_p, const uint8_t* __restrict a_base_p) { | ||
auto out = reinterpret_cast<uint8_t *>(a_out_p); | ||
const auto in = reinterpret_cast<const uint8_t *>(a_in_p); | ||
const auto base = reinterpret_cast<const uint8_t *>(a_base_p); | ||
|
||
for (auto lane = 0U; lane < Helper<T>::num_lanes; ++lane) { | ||
uint8_t register_0; | ||
uint8_t tmp; | ||
tmp = base[lane]; | ||
loop<T, Helper<T>::num_bits>([lane, base, in, &tmp, &out, ®ister_0](auto j) { | ||
register_0 = in[index(j, lane)]; | ||
tmp = tmp + register_0; | ||
out[index(j, lane)] = tmp; | ||
}); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
} // nam |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* Copyright 2024 Man Group Operations Limited | ||
* | ||
* Use of this software is governed by the Business Source License 1.1 included in the file licenses/BSL.txt. | ||
* | ||
* As of the Change Date specified in that file, in accordance with the Business Source License, use of this software will be governed by the Apache License, version 2.0. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <utility> | ||
#include <limits> | ||
|
||
namespace arcticdb { | ||
namespace detail { | ||
|
||
constexpr std::size_t FastLanesWidth = 1024; | ||
|
||
template<class T, T... inds, class F> | ||
constexpr void loop(std::integer_sequence<T, inds...>, F &&f) { | ||
(f(std::integral_constant<T, inds>{}), ...); | ||
} | ||
} | ||
|
||
template<class T, T count, class F> | ||
constexpr void loop(F &&f) { | ||
detail::loop(std::make_integer_sequence<T, count>{}, std::forward<F>(f)); | ||
} | ||
|
||
template<typename T> | ||
constexpr size_t type_bits() { | ||
return sizeof(T) * std::numeric_limits<uint8_t>::digits; | ||
} | ||
|
||
template<typename T> | ||
struct Helper { | ||
static constexpr size_t num_bits = type_bits<T>(); | ||
static constexpr size_t register_width = detail::FastLanesWidth; | ||
static constexpr size_t num_lanes = register_width / num_bits; | ||
}; | ||
|
||
static_assert(Helper<uint64_t>::num_lanes == 16); | ||
static_assert(Helper<uint8_t>::num_lanes == 128); | ||
static_assert(Helper<uint16_t>::num_bits == 16); | ||
|
||
constexpr std::array<size_t, 8> FL_ORDER = { 0, 4, 2, 6, 1, 5, 3, 7 }; | ||
|
||
constexpr size_t transposed_index(size_t index) { | ||
auto lane = index % 16; | ||
auto order = (index / 16) % 8; | ||
auto row = index / 128; | ||
|
||
return (lane * 64) + (FL_ORDER[order] * 8) + row; | ||
} | ||
|
||
constexpr size_t index(size_t row, size_t lane) { | ||
const auto o = row / 8; | ||
const auto s = row % 8; | ||
return (FL_ORDER[o] * 16) + (s * 128) + lane; | ||
} | ||
|
||
static_assert(transposed_index(1) == 64); | ||
static_assert(transposed_index(57) == 624); | ||
static_assert(transposed_index(1022) == 959); | ||
|
||
static_assert(index(1, 0) == 128); | ||
static_assert(transposed_index(57) == 624); | ||
static_assert(transposed_index(1022) == 959); | ||
} // namespace arcticdb |
Oops, something went wrong.