Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
02e3d8d
prelim
nirandaperera Jun 8, 2021
fad0383
working - not tested properly. requires clean up
nirandaperera Jun 9, 2021
1ffce3f
adding striding
nirandaperera Jun 9, 2021
35f6178
adding tests
nirandaperera Jun 9, 2021
f0f3c83
moving BitmapWordReader and BitmapWordWriter to header files
nirandaperera Jun 9, 2021
7c6a4ef
adding multiple writers and testing w/ offsets
nirandaperera Jun 11, 2021
1e22301
Autoformat/render all the things [automated commit]
nirandaperera Jun 11, 2021
15bdd4b
Revert "Autoformat/render all the things [automated commit]"
nirandaperera Jun 11, 2021
b00a8a0
removing std::function visitor and adding direct ref template
nirandaperera Jun 11, 2021
2743309
simplifying impl
nirandaperera Jun 11, 2021
4907fa0
adding byte visitor to clean up the code
nirandaperera Jun 11, 2021
3af7137
adding changes to kleene kernels
nirandaperera Jun 11, 2021
cc659e9
fix for kleene test failures with NullHandling::COMPUTED_PREALLOCATE …
nirandaperera Jun 12, 2021
a0b4b42
adding set/clear bitmap methods
nirandaperera Jun 14, 2021
aea1b0f
lint fixes
nirandaperera Jun 14, 2021
6f30a98
adding SpliceWord and refactoring code
nirandaperera Jun 14, 2021
40ba1c7
refactor
nirandaperera Jun 14, 2021
ae38c47
adding benchmark
nirandaperera Jun 16, 2021
e25a0d2
adding benchmark1
nirandaperera Jun 16, 2021
bd7463a
Revert "adding benchmark1"
nirandaperera Jun 17, 2021
8390422
adding do not optimize
nirandaperera Jun 17, 2021
952015a
adding ifelse bench
nirandaperera Jun 17, 2021
588373b
adding offset bench
nirandaperera Jun 17, 2021
ec127b7
replacing bitblockcounter in ifelse
nirandaperera Jun 17, 2021
8d9023c
replacing bitblockcounter in ifelse
nirandaperera Jun 17, 2021
4e640b1
extending bench suite
nirandaperera Jun 17, 2021
d9ee399
Update cpp/src/arrow/compute/kernels/scalar_boolean.cc
nirandaperera Jun 17, 2021
197e1c4
Apply suggestions from code review
nirandaperera Jun 17, 2021
4c7f445
adding PR comments
nirandaperera Jun 17, 2021
b12a20d
fixing errors
nirandaperera Jun 18, 2021
a20e295
simplifying if-else
nirandaperera Jun 18, 2021
e37be50
simplifying if-else
nirandaperera Jun 18, 2021
6c71c36
fixing errors
nirandaperera Jun 18, 2021
aeb48ae
attempting to fix msvc error
nirandaperera Jun 19, 2021
4519dd3
lint fix
nirandaperera Jun 19, 2021
30ec72e
fixing the down casting issue
nirandaperera Jun 19, 2021
0e4f1a0
fixing the down casting issue
nirandaperera Jun 19, 2021
f5a14c0
refactor
nirandaperera Jun 19, 2021
cfb88f8
adding set/clearbitmap tests
nirandaperera Jun 21, 2021
33444d1
making if_else kernels write_to_slices
nirandaperera Jun 21, 2021
984b7db
fixing lint
nirandaperera Jun 21, 2021
adfb0fd
fixing performance isssue
nirandaperera Jun 28, 2021
6d48f7a
dummy
nirandaperera Jun 28, 2021
d368866
Revert "dummy"
nirandaperera Jun 28, 2021
4324a73
Apply suggestions from code review
nirandaperera Jun 28, 2021
1b3144b
applying PR comments
nirandaperera Jun 28, 2021
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
1 change: 1 addition & 0 deletions cpp/src/arrow/compute/kernels/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ add_arrow_benchmark(scalar_arithmetic_benchmark PREFIX "arrow-compute")
add_arrow_benchmark(scalar_boolean_benchmark PREFIX "arrow-compute")
add_arrow_benchmark(scalar_cast_benchmark PREFIX "arrow-compute")
add_arrow_benchmark(scalar_compare_benchmark PREFIX "arrow-compute")
add_arrow_benchmark(scalar_if_else_benchmark PREFIX "arrow-compute")
add_arrow_benchmark(scalar_set_lookup_benchmark PREFIX "arrow-compute")
add_arrow_benchmark(scalar_string_benchmark PREFIX "arrow-compute")

Expand Down
77 changes: 37 additions & 40 deletions cpp/src/arrow/compute/kernels/scalar_boolean.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,60 +30,60 @@ namespace compute {

namespace {

enum BitmapIndex { LEFT_VALID, LEFT_DATA, RIGHT_VALID, RIGHT_DATA };

template <typename ComputeWord>
void ComputeKleene(ComputeWord&& compute_word, KernelContext* ctx, const ArrayData& left,
const ArrayData& right, ArrayData* out) {
DCHECK(left.null_count != 0 || right.null_count != 0)
<< "ComputeKleene is unnecessarily expensive for the non-null case";

Bitmap bitmaps[4];
bitmaps[LEFT_VALID] = {left.buffers[0], left.offset, left.length};
bitmaps[LEFT_DATA] = {left.buffers[1], left.offset, left.length};
Bitmap left_valid_bm{left.buffers[0], left.offset, left.length};
Bitmap left_data_bm{left.buffers[1], left.offset, left.length};

bitmaps[RIGHT_VALID] = {right.buffers[0], right.offset, right.length};
bitmaps[RIGHT_DATA] = {right.buffers[1], right.offset, right.length};
Bitmap right_valid_bm{right.buffers[0], right.offset, right.length};
Bitmap right_data_bm{right.buffers[1], right.offset, right.length};

auto out_validity = out->GetMutableValues<uint64_t>(0);
auto out_data = out->GetMutableValues<uint64_t>(1);
std::array<Bitmap, 2> out_bms{Bitmap(out->buffers[0], out->offset, out->length),
Bitmap(out->buffers[1], out->offset, out->length)};

int64_t i = 0;
auto apply = [&](uint64_t left_valid, uint64_t left_data, uint64_t right_valid,
uint64_t right_data) {
uint64_t right_data, uint64_t* out_validity, uint64_t* out_data) {
auto left_true = left_valid & left_data;
auto left_false = left_valid & ~left_data;

auto right_true = right_valid & right_data;
auto right_false = right_valid & ~right_data;

compute_word(left_true, left_false, right_true, right_false, &out_validity[i],
&out_data[i]);
++i;
compute_word(left_true, left_false, right_true, right_false, out_validity, out_data);
};

if (right.null_count == 0) {
// bitmaps[RIGHT_VALID] might be null; override to make it safe for Visit()
bitmaps[RIGHT_VALID] = bitmaps[RIGHT_DATA];
Bitmap::VisitWords(bitmaps, [&](std::array<uint64_t, 4> words) {
apply(words[LEFT_VALID], words[LEFT_DATA], ~uint64_t(0), words[RIGHT_DATA]);
});
std::array<Bitmap, 3> in_bms{left_valid_bm, left_data_bm, right_data_bm};
Bitmap::VisitWordsAndWrite(
in_bms, &out_bms,
[&](const std::array<uint64_t, 3>& in, std::array<uint64_t, 2>* out) {
apply(in[0], in[1], ~uint64_t(0), in[2], &(out->at(0)), &(out->at(1)));
});
return;
}

if (left.null_count == 0) {
// bitmaps[LEFT_VALID] might be null; override to make it safe for Visit()
bitmaps[LEFT_VALID] = bitmaps[LEFT_DATA];
Bitmap::VisitWords(bitmaps, [&](std::array<uint64_t, 4> words) {
apply(~uint64_t(0), words[LEFT_DATA], words[RIGHT_VALID], words[RIGHT_DATA]);
});
std::array<Bitmap, 3> in_bms{left_data_bm, right_valid_bm, right_data_bm};
Bitmap::VisitWordsAndWrite(
in_bms, &out_bms,
[&](const std::array<uint64_t, 3>& in, std::array<uint64_t, 2>* out) {
apply(~uint64_t(0), in[0], in[1], in[2], &(out->at(0)), &(out->at(1)));
});
return;
}

DCHECK(left.null_count != 0 && right.null_count != 0);
Bitmap::VisitWords(bitmaps, [&](std::array<uint64_t, 4> words) {
apply(words[LEFT_VALID], words[LEFT_DATA], words[RIGHT_VALID], words[RIGHT_DATA]);
});
std::array<Bitmap, 4> in_bms{left_valid_bm, left_data_bm, right_valid_bm,
right_data_bm};
Bitmap::VisitWordsAndWrite(
in_bms, &out_bms,
[&](const std::array<uint64_t, 4>& in, std::array<uint64_t, 2>* out) {
apply(in[0], in[1], in[2], in[3], &(out->at(0)), &(out->at(1)));
});
}

inline BooleanScalar InvertScalar(const Scalar& in) {
Expand Down Expand Up @@ -204,7 +204,8 @@ struct KleeneAndOp : Commutative<KleeneAndOp> {
ArrayData* out) {
if (left.GetNullCount() == 0 && right.GetNullCount() == 0) {
out->null_count = 0;
out->buffers[0] = nullptr;
// Kleene kernels have validity bitmap pre-allocated. Therefore, set it to 1
BitUtil::SetBitmap(out->buffers[0]->mutable_data(), out->offset, out->length);
return AndOp::Call(ctx, left, right, out);
}
auto compute_word = [](uint64_t left_true, uint64_t left_false, uint64_t right_true,
Expand Down Expand Up @@ -307,7 +308,8 @@ struct KleeneOrOp : Commutative<KleeneOrOp> {
ArrayData* out) {
if (left.GetNullCount() == 0 && right.GetNullCount() == 0) {
out->null_count = 0;
out->buffers[0] = nullptr;
// Kleene kernels have validity bitmap pre-allocated. Therefore, set it to 1
BitUtil::SetBitmap(out->buffers[0]->mutable_data(), out->offset, out->length);
return OrOp::Call(ctx, left, right, out);
}

Expand Down Expand Up @@ -437,7 +439,8 @@ struct KleeneAndNotOp {
ArrayData* out) {
if (left.GetNullCount() == 0 && right.GetNullCount() == 0) {
out->null_count = 0;
out->buffers[0] = nullptr;
// Kleene kernels have validity bitmap pre-allocated. Therefore, set it to 1
BitUtil::SetBitmap(out->buffers[0]->mutable_data(), out->offset, out->length);
return AndNotOp::Call(ctx, left, right, out);
}

Expand All @@ -453,17 +456,15 @@ struct KleeneAndNotOp {
}
};

void MakeFunction(std::string name, int arity, ArrayKernelExec exec,
void MakeFunction(const std::string& name, int arity, ArrayKernelExec exec,
const FunctionDoc* doc, FunctionRegistry* registry,
bool can_write_into_slices = true,
NullHandling::type null_handling = NullHandling::INTERSECTION) {
auto func = std::make_shared<ScalarFunction>(name, Arity(arity), doc);

// Scalar arguments not yet supported
std::vector<InputType> in_types(arity, InputType(boolean()));
ScalarKernel kernel(std::move(in_types), boolean(), exec);
kernel.null_handling = null_handling;
kernel.can_write_into_slices = can_write_into_slices;

DCHECK_OK(func->AddKernel(kernel));
DCHECK_OK(registry->AddFunction(std::move(func)));
Expand Down Expand Up @@ -549,16 +550,12 @@ void RegisterScalarBoolean(FunctionRegistry* registry) {
MakeFunction("or", 2, applicator::SimpleBinary<OrOp>, &or_doc, registry);
MakeFunction("xor", 2, applicator::SimpleBinary<XorOp>, &xor_doc, registry);

// The Kleene logic kernels cannot write into sliced output bitmaps
MakeFunction("and_kleene", 2, applicator::SimpleBinary<KleeneAndOp>, &and_kleene_doc,
registry,
/*can_write_into_slices=*/false, NullHandling::COMPUTED_PREALLOCATE);
registry, NullHandling::COMPUTED_PREALLOCATE);
MakeFunction("and_not_kleene", 2, applicator::SimpleBinary<KleeneAndNotOp>,
&and_not_kleene_doc, registry,
/*can_write_into_slices=*/false, NullHandling::COMPUTED_PREALLOCATE);
&and_not_kleene_doc, registry, NullHandling::COMPUTED_PREALLOCATE);
MakeFunction("or_kleene", 2, applicator::SimpleBinary<KleeneOrOp>, &or_kleene_doc,
registry,
/*can_write_into_slices=*/false, NullHandling::COMPUTED_PREALLOCATE);
registry, NullHandling::COMPUTED_PREALLOCATE);
}

} // namespace internal
Expand Down
Loading