Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compiled binary operation #8192

Merged
merged 86 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
30f1cc4
replace timestamps class with chrono time_point
karthikeyann May 7, 2021
7c7e190
update bool random generator, static fns in fixture
karthikeyann May 10, 2021
c71480d
add binary_operation_compiled (fixed width: add, sub, mul, div, truediv)
karthikeyann May 10, 2021
0c248b0
add BinaryOperationCompiledTest
karthikeyann May 10, 2021
a88ddfc
Merge branch 'branch-0.20' of github.com:rapidsai/cudf into fea-binop…
karthikeyann May 10, 2021
0d46787
use is_invocable() on Ops functor
karthikeyann May 11, 2021
c4283c9
remove <OPS>Exists traits
karthikeyann May 11, 2021
5a9bcb5
add ADD, SUB, MUL, DIV type tests
karthikeyann May 11, 2021
7445f82
add more binary operators to compiled binary ops
karthikeyann May 13, 2021
65b187e
add is_supported_operation for binary ops
karthikeyann May 13, 2021
ac24b51
add unit test for newly added binary operators
karthikeyann May 13, 2021
53a800f
fix Pow, LogBase, ATan2 unit tests
karthikeyann May 17, 2021
a669538
add compiled binaryop benchmark
karthikeyann May 17, 2021
245434a
split binary ops to seperate files (1 TU per operation)
karthikeyann May 18, 2021
158a2b0
reorg functors (to improve compile time)
karthikeyann May 19, 2021
04acf3b
add unit test for Bit Operations
karthikeyann May 19, 2021
5ffb5a5
fix Pow unit test (undefined behavior), style fix
karthikeyann May 19, 2021
88b5c86
add logical operations unit tests
karthikeyann May 19, 2021
d648351
add comparison unit tests
karthikeyann May 19, 2021
b2cf731
add decimal support, add decimal type to comparison unit tests
karthikeyann May 19, 2021
a3e1bf3
Merge branch 'branch-21.06' of github.com:rapidsai/cudf into fea-bino…
karthikeyann May 20, 2021
ddec58f
add decimal support, unit tests (default scale)
karthikeyann May 20, 2021
b1454da
cleanup
karthikeyann May 20, 2021
3eb4d0d
Merge branch 'branch-21.06' of github.com:rapidsai/cudf into fea-bino…
karthikeyann May 21, 2021
b9a4d4c
review comments
karthikeyann May 24, 2021
07dc42f
decimal support with integral types mul, div, truediv, floordiv
karthikeyann May 24, 2021
fcc6ba2
fixed_point support more types conversion, fp unit tests
karthikeyann May 25, 2021
f85d809
fix benchmark for binop type in tparam
karthikeyann May 25, 2021
320e4dc
merge equality ops, comparison ops to single files (reduce lib size)
karthikeyann May 25, 2021
6b71090
Add NullsEqual operator
karthikeyann May 25, 2021
c564f85
address review comments (if constexpr, is_invocable_v)
karthikeyann May 25, 2021
ca93e01
remove anon namespace , fix unused arg due to if constexpr
karthikeyann May 28, 2021
71ef168
remove using cuda::std
karthikeyann May 28, 2021
cac3239
reduce compile time for bool result ops: comparison, logical ops
karthikeyann May 28, 2021
c69c28a
remove unused headers, extern template declarations
karthikeyann May 31, 2021
ae7073e
rename functions, moved to headers
karthikeyann May 31, 2021
5fba4a2
move NullEquals specialization to equality_ops.cu
karthikeyann Jun 2, 2021
bd0778b
add NullMax, NullMin, unit tests
karthikeyann Jun 2, 2021
ee74865
remove dead code, comments
karthikeyann Jun 2, 2021
69c8cb1
move compiled binary_operation to cudf::experimental
karthikeyann Jun 2, 2021
4fc6a7c
better name for individual op apply_binary_op
karthikeyann Jun 2, 2021
1892b20
copyright year update
karthikeyann Jun 2, 2021
f2008c7
add missing NullMax, NullMin files
karthikeyann Jun 2, 2021
c316c0e
Merge branch 'branch-21.06' of github.com:rapidsai/cudf into fea-bino…
karthikeyann Jun 2, 2021
b8fa814
use if constexpr instead of Null ops specializations
karthikeyann Jun 7, 2021
a3c7dd1
add scalar support to compiled binops
karthikeyann Jun 7, 2021
5859fac
add all scalar fixed_point binops tests
karthikeyann Jun 7, 2021
5cc5d96
Merge branch 'branch-21.08' of github.com:rapidsai/cudf into fea-bino…
karthikeyann Jun 7, 2021
d3ebee6
fix PMod bug, add PMod tests
karthikeyann Jun 7, 2021
75f89ba
add PyMod unit tests
karthikeyann Jun 7, 2021
cb7b18b
fix NullEquals, NullMax, NullMin scalar failures
karthikeyann Jun 7, 2021
5ddee92
make NullEquals args similar to NullMax, NullMin
karthikeyann Jun 7, 2021
0d22c54
take care of common_type_t, reduce compile time (5s)
karthikeyann Jun 7, 2021
8f12a50
add NullEquals test, reorg NullOp test methods
karthikeyann Jun 7, 2021
8f66917
cleanup includes, add documentation
karthikeyann Jun 10, 2021
aad4845
Merge branch 'branch-21.08' of github.com:rapidsai/cudf into fea-bino…
karthikeyann Jun 10, 2021
05ba2bf
fix missing column_device_view.cuh include
karthikeyann Jun 10, 2021
a587e80
remove COALESCE op, reorder binary_operator enum
karthikeyann Jun 10, 2021
2474ae0
logical types benchmark output bool types only
karthikeyann Jun 10, 2021
e8256e4
fix typo
karthikeyann Jun 11, 2021
16e3db7
replace thrust::for_each with own for_each_kernel
karthikeyann Jun 16, 2021
5dfc3a7
Merge branch 'branch-21.08' of github.com:rapidsai/cudf into fea-bino…
karthikeyann Jun 16, 2021
36a9d85
fix 11.0 NullMax, NullMin failure: change bool to bool&
karthikeyann Jun 16, 2021
cd8b33a
add NullMax, NullMin, & other ops to benchmarks
karthikeyann Jun 16, 2021
c7b394b
reorder ops
karthikeyann Jun 16, 2021
8560a34
add NullEquals string test
karthikeyann Jun 16, 2021
738a2a8
replace String compiled binary_ops with experiemntal::binary_operation
karthikeyann Jun 22, 2021
4f1ad6a
split comparison ops to seperate files (for performance improvement)
karthikeyann Jun 24, 2021
89f7a4c
replace store_as_result with is_bool_result()
karthikeyann Jun 24, 2021
6702a02
cleanup includes
karthikeyann Jun 25, 2021
b74ecf8
reoorg code, remove binops_custom.cu
karthikeyann Jun 25, 2021
c61f6b0
rename binops_custom.cuh to binary_ops.cuh
karthikeyann Jun 25, 2021
9a36be7
remove has_common_type_v to main traits.hpp
karthikeyann Jul 8, 2021
194f082
templatized experiemental::detail::binary_operation
karthikeyann Jul 8, 2021
004ebca
cleanup unit tests
karthikeyann Jul 8, 2021
4aea06a
rename _Pow tests to _FloatOps tests
karthikeyann Jul 9, 2021
e521c4e
update is_bool_result with invoke_result_t bool
karthikeyann Jul 9, 2021
5aafa24
reduce repitition in unit tests
karthikeyann Jul 9, 2021
a04f44d
add scalar tests to binops unit tests
karthikeyann Jul 9, 2021
d2292ad
add explicit operator value_type to fixed_point scalar
karthikeyann Jul 9, 2021
ea6f323
add string_scalar random generator for binops tests
karthikeyann Jul 9, 2021
80a2d08
Merge branch 'branch-21.08' of github.com:rapidsai/cudf into fea-bino…
karthikeyann Jul 9, 2021
84ffbe7
style fix
karthikeyann Jul 9, 2021
b674b6f
Merge branch 'branch-21.08' of github.com:rapidsai/cudf into fea-bino…
karthikeyann Jul 12, 2021
7e6abc8
move triats _impl to detail namespace
karthikeyann Jul 12, 2021
ac6edb1
ambiguous struct fix, style fix
karthikeyann Jul 12, 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
2 changes: 2 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ add_library(cudf
src/ast/transform.cu
src/binaryop/binaryop.cpp
src/binaryop/compiled/binary_ops.cu
src/binaryop/compiled/binops_custom.cu
robertmaynard marked this conversation as resolved.
Show resolved Hide resolved
src/binaryop/compiled/util.cpp
src/labeling/label_bins.cu
src/bitmask/null_mask.cu
src/bitmask/is_element_valid.cpp
Expand Down
7 changes: 7 additions & 0 deletions cpp/include/cudf/binaryop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,12 @@ cudf::data_type binary_operation_fixed_point_output_type(binary_operator op,
cudf::data_type const& lhs,
cudf::data_type const& rhs);

std::unique_ptr<column> binary_operation_compiled(
karthikeyann marked this conversation as resolved.
Show resolved Hide resolved
column_view const& lhs,
column_view const& rhs,
binary_operator op,
data_type output_type,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource());

/** @} */ // end of group
} // namespace cudf
14 changes: 1 addition & 13 deletions cpp/include/cudf/wrappers/timestamps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,7 @@ template <class Duration>
using time_point = cuda::std::chrono::sys_time<Duration>;

template <class Duration>
struct timestamp : time_point<Duration> {
// Bring over base class constructors and make them visible here
using time_point<Duration>::time_point;

// This is needed as __shared__ objects of this type can't be assigned in device code
// when the initializer list constructs subobjects with values, which is what std::time_point
// does.
constexpr timestamp() : time_point<Duration>(Duration()){};

// The inherited copy constructor will hide the auto generated copy constructor;
// hence, explicitly define and delegate
constexpr timestamp(const time_point<Duration>& other) : time_point<Duration>(other) {}
};
using timestamp = time_point<Duration>;
} // namespace detail

/**
Expand Down
11 changes: 10 additions & 1 deletion cpp/include/cudf_test/base_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,23 @@ class UniformRandomGenerator {
* @param lower Lower bound of the range
* @param upper Upper bound of the desired range
*/
template <typename TL = T, std::enable_if_t<!cudf::is_chrono<TL>()> * = nullptr>
template <typename TL = T,
std::enable_if_t<!cudf::is_chrono<TL>() && !cudf::is_boolean<TL>()> * = nullptr>
UniformRandomGenerator(T lower,
T upper,
uint64_t seed = detail::random_generator_incrementing_seed())
: dist{lower, upper}, rng{std::mt19937_64{seed}()}
{
}

template <typename TL = T, std::enable_if_t<cudf::is_boolean<TL>()> * = nullptr>
UniformRandomGenerator(T lower,
T upper,
uint64_t seed = detail::random_generator_incrementing_seed())
: dist{0.5}, rng{std::mt19937_64{seed}()}
{
}

/**
* @brief Construct a new Uniform Random Generator to generate uniformly
* random numbers in the range `[upper,lower]`
Expand Down
227 changes: 227 additions & 0 deletions cpp/src/binaryop/compiled/binops_custom.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/*
* Copyright (c) 2021, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "binary_ops.hpp"
#include "operation.cuh"

#include <cudf/binaryop.hpp>
#include <cudf/column/column_factories.hpp>
#include <cudf/detail/iterator.cuh>
#include <cudf/detail/null_mask.hpp>
#include <cudf/detail/nvtx/ranges.hpp>
#include <cudf/scalar/scalar_device_view.cuh>
#include <cudf/table/table_view.hpp>
#include <cudf/utilities/span.hpp>

#include <binaryop/jit/operation.hpp>

#include <rmm/cuda_stream_view.hpp>
#include <rmm/device_uvector.hpp>
#include <rmm/exec_policy.hpp>

namespace cudf {

namespace binops {
namespace compiled {
namespace {
// Struct to launch only defined operations.
template <typename BinaryOperator>
struct ops_wrapper {
template <typename T, typename... Args>
__device__ enable_if_t<BinaryOperator::template is_supported<T>(), void> operator()(Args... args)
{
BinaryOperator{}.template operator()<T>(std::forward<Args>(args)...);
}

template <typename T, typename... Args>
__device__ enable_if_t<not BinaryOperator::template is_supported<T>(), void> operator()(
Args... args)
{
}
};

// TODO merge these 2 structs somehow.
template <typename BinaryOperator>
struct ops2_wrapper {
template <typename T1, typename T2, typename... Args>
__device__ enable_if_t<BinaryOperator::template is_supported<T1, T2>(), void> operator()(
Args... args)
{
BinaryOperator{}.template operator()<T1, T2>(std::forward<Args>(args)...);
}

template <typename T1, typename T2, typename... Args>
__device__ enable_if_t<not BinaryOperator::template is_supported<T1, T2>(), void> operator()(
Args... args)
{
}
};

struct operator_dispatcher {
//, OperatorType type)
// (type == OperatorType::Direct ? operator_name : 'R' + operator_name);
data_type common_data_type;
mutable_column_device_view out;
column_device_view lhs;
column_device_view rhs;
binary_operator op;
operator_dispatcher(data_type ct,
mutable_column_device_view ot,
column_device_view lt,
column_device_view rt,
binary_operator op)
: common_data_type(ct), out(ot), lhs(lt), rhs(rt), op(op)
{
}

template <class BinaryOperator>
inline __device__ void dispatch_single_double(size_type i)
{
if (common_data_type == data_type{type_id::EMPTY}) {
double_type_dispatcher(
lhs.type(), rhs.type(), ops2_wrapper<BinaryOperator>{}, i, lhs, rhs, out);
} else
type_dispatcher(common_data_type, ops_wrapper<BinaryOperator>{}, i, lhs, rhs, out);
}

__device__ void operator()(size_type i)
{
// clang-format off
switch (op) {
// TODO One more level of indirection to allow double type dispatching for chrono types.
case binary_operator::ADD: dispatch_single_double<Add>(i); break;
case binary_operator::SUB: dispatch_single_double<Sub>(i); break;
case binary_operator::MUL: dispatch_single_double<Mul>(i); break;
case binary_operator::DIV: dispatch_single_double<Div>(i); break;
case binary_operator::TRUE_DIV: dispatch_single_double<TrueDiv>(i); break;
/*
case binary_operator::FLOOR_DIV: FloorDiv;
case binary_operator::MOD: Mod;
case binary_operator::PYMOD: PyMod;
case binary_operator::POW: Pow;
case binary_operator::EQUAL: Equal;
case binary_operator::NOT_EQUAL: NotEqual;
case binary_operator::LESS: Less;
case binary_operator::GREATER: Greater;
case binary_operator::LESS_EQUAL: LessEqual;
case binary_operator::GREATER_EQUAL: GreaterEqual;
case binary_operator::BITWISE_AND: BitwiseAnd;
case binary_operator::BITWISE_OR: BitwiseOr;
case binary_operator::BITWISE_XOR: BitwiseXor;
case binary_operator::LOGICAL_AND: LogicalAnd;
case binary_operator::LOGICAL_OR: LogicalOr;
case binary_operator::GENERIC_BINARY: UserDefinedOp;
case binary_operator::SHIFT_LEFT: ShiftLeft;
case binary_operator::SHIFT_RIGHT: ShiftRight;
case binary_operator::SHIFT_RIGHT_UNSIGNED: ShiftRightUnsigned;
case binary_operator::LOG_BASE: LogBase;
case binary_operator::ATAN2: ATan2;
case binary_operator::PMOD: PMod;
case binary_operator::NULL_EQUALS: NullEquals;
case binary_operator::NULL_MAX: NullMax;
case binary_operator::NULL_MIN: NullMin; */
default: ;
}
// clang-format on
}
};

} // namespace

void binary_operation_compiled(mutable_column_view& out,
column_view const& lhs,
column_view const& rhs,
binary_operator op,
rmm::cuda_stream_view stream)
{
if (is_null_dependent(op)) {
CUDF_FAIL("Unsupported yet");
// cudf::binops::jit::kernel_v_v_with_validity
} else {
// Create binop functor instance
auto lhsd = column_device_view::create(lhs, stream);
auto rhsd = column_device_view::create(rhs, stream);
auto outd = mutable_column_device_view::create(out, stream);
// auto binop_func = device_dispatch_functor<cudf::binops::jit::Add2>{*lhsd, *rhsd, *outd};

// TODO move to utility.
auto common_dtype = get_common_type(out.type(), lhs.type(), rhs.type());
if (not(op == binary_operator::ADD or op == binary_operator::SUB or
op == binary_operator::MUL or op == binary_operator::DIV or
op == binary_operator::TRUE_DIV))
CUDF_FAIL("Unsupported operator");
// Execute it on every element
thrust::for_each(rmm::exec_policy(stream),
thrust::make_counting_iterator<size_type>(0),
thrust::make_counting_iterator<size_type>(out.size()),
operator_dispatcher{common_dtype, *outd, *lhsd, *rhsd, op});
//"cudf::binops::jit::kernel_v_v") //
}
}
} // namespace compiled
} // namespace binops

namespace detail {

std::unique_ptr<column> make_fixed_width_column_for_output(column_view const& lhs,
column_view const& rhs,
binary_operator op,
data_type output_type,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr);

std::unique_ptr<column> binary_operation_compiled(column_view const& lhs,
column_view const& rhs,
binary_operator op,
data_type output_type,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr)
{
CUDF_EXPECTS(lhs.size() == rhs.size(), "Column sizes don't match");

if (lhs.type().id() == type_id::STRING and rhs.type().id() == type_id::STRING)
return binops::compiled::binary_operation(lhs, rhs, op, output_type, stream, mr);

if (is_fixed_point(lhs.type()) or is_fixed_point(rhs.type()))
CUDF_FAIL("Not yet supported fixed_point");
// return fixed_point_binary_operation(lhs, rhs, op, output_type, stream, mr);

// Check for datatype
CUDF_EXPECTS(is_fixed_width(output_type), "Invalid/Unsupported output datatype");
CUDF_EXPECTS(is_fixed_width(lhs.type()), "Invalid/Unsupported lhs datatype");
CUDF_EXPECTS(is_fixed_width(rhs.type()), "Invalid/Unsupported rhs datatype");

auto out = make_fixed_width_column_for_output(lhs, rhs, op, output_type, stream, mr);

if (lhs.is_empty() or rhs.is_empty()) return out;

auto out_view = out->mutable_view();
// CUDF_FAIL("Not yet supported fixed_width");
binops::compiled::binary_operation_compiled(out_view, lhs, rhs, op, stream);
return out;
}
} // namespace detail

std::unique_ptr<column> binary_operation_compiled(column_view const& lhs,
column_view const& rhs,
binary_operator op,
data_type output_type,
rmm::mr::device_memory_resource* mr)
{
CUDF_FUNC_RANGE();
return detail::binary_operation_compiled(lhs, rhs, op, output_type, rmm::cuda_stream_default, mr);
}
} // namespace cudf
Loading