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

[REVIEW] Port unary to libcudf++ #3214

Merged
merged 47 commits into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
14a3f63
[WIP] Port unary to libcudf++
Oct 25, 2019
e919b4b
Merge branch 'branch-0.11' into fea-port-unary
codereport Oct 28, 2019
a83a1c7
[ISSUE] 2950
codereport Oct 28, 2019
08d2154
Merge branch 'branch-0.11' into fea-port-unary
codereport Oct 28, 2019
4e9c944
[WIP] Port unary to libcudf++
codereport Oct 28, 2019
9f39da7
Merge branch 'branch-0.11' into fea-port-unary
codereport Oct 29, 2019
ac250c5
Merge branch 'branch-0.11' into fea-port-unary
codereport Oct 30, 2019
d874e7c
Update cpp/src/unary/math_ops.cu
codereport Oct 31, 2019
587c4f9
Update cpp/src/unary/unary_ops.cuh
codereport Oct 31, 2019
25c5db1
Update cpp/src/unary/unary_ops.cuh
codereport Oct 31, 2019
32e9207
Addressing Mark's comments
codereport Oct 31, 2019
710cad6
Merge branch 'branch-0.11' into fea-port-unary
codereport Oct 31, 2019
856d136
Merge branch 'fea-port-unary' of https://github.com/codereport/cudf i…
codereport Oct 31, 2019
1c5e3fe
Upgrade gpu_op_kernel to thrust::transform
codereport Nov 1, 2019
ed88761
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 1, 2019
ee58531
Merge remote-tracking branch 'upstream/branch-0.11' into fea-port-unary
codereport Nov 1, 2019
9cfaa1f
Add cast_ops - pre port
codereport Nov 1, 2019
da7c8d5
Merge branch 'fea-port-unary' of https://github.com/codereport/cudf i…
Nov 3, 2019
259fbcd
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 4, 2019
f3e6859
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 7, 2019
5529345
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 18, 2019
54d3624
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 19, 2019
db5ed94
Merge remote-tracking branch 'origin/fea-port-unary' into fea-port-unary
Nov 19, 2019
11a1968
Remove gdf_error from unary_ops
Nov 19, 2019
b0b122c
Replace gdf_num_bitmask elements with cudf::num_bitmask_words
Nov 19, 2019
5299273
Remove cast_ops and update CMakeLists.txt
Nov 19, 2019
1e078ee
Merge branch 'branch-0.11' into fea-port-unary
Nov 19, 2019
afbd31e
Merge branch 'branch-0.11' into fea-port-unary
Nov 22, 2019
09cecdf
Merge branch 'branch-0.11' into fea-port-unary
Nov 23, 2019
53ae13e
Remove legacy headers from math_ops.cu
Nov 24, 2019
174d3a0
Remove legacy headers from math_ops.cu
Nov 24, 2019
775389b
Merge branch 'fea-port-unary' of https://github.com/codereport/cudf i…
codereport Nov 24, 2019
446bdca
Clean up legacy/unary_ops_test.cu
codereport Nov 24, 2019
2d8fe08
Fix CHANGELOG.md file
codereport Nov 24, 2019
194e2e6
Renaming functions / structs from CR
codereport Nov 24, 2019
dc514c1
Initial unary port tests
codereport Nov 25, 2019
2f6e524
Remove tabs from unary_ops_tests
codereport Nov 25, 2019
317c199
Extra unary ops tests
codereport Nov 25, 2019
789610d
Extra unary ops tests
codereport Nov 25, 2019
067dd12
Merge remote-tracking branch 'origin/fea-port-unary' into fea-port-unary
codereport Nov 25, 2019
fe7ee5e
Small fix and clean up of handle_checks_and_validity
codereport Nov 25, 2019
a1d3c07
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 25, 2019
feba50b
Responding to CR comments:
codereport Nov 26, 2019
088e3ad
Responding to CR comments:
codereport Nov 26, 2019
480ac5b
Refactor of dispatcher/launcher to return column_view
codereport Nov 26, 2019
870d7a1
Responding to CR comments:
codereport Nov 27, 2019
d931b0a
Merge branch 'branch-0.11' into fea-port-unary
codereport Nov 27, 2019
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
- PR #3128 Support MultiIndex in DataFrame.join
- PR #3135 Add nvtx utilities to cudf::nvtx namespace
- PR #3021 Java host side concat of serialized buffers
- PR #3138 Movey unary files to legacy
- PR #3138 Move unary files to legacy
- PR #3154 Make `table_view_base.column()` const and add `mutable_table_view.column()`
- PR #3175 Set cmake cuda version variables
- PR #3171 Move deprecated error macros to legacy
Expand All @@ -65,6 +65,7 @@
- PR #3202 Rename and move error.hpp to public headers
- PR #2878 Use upstream merge code in dask_cudf
- PR #3157 Use enum class rather than enum for mask_allocation_policy
- PR #3214 Port unary to libcudf++
codereport marked this conversation as resolved.
Show resolved Hide resolved

## Bug Fixes

Expand Down
1 change: 1 addition & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ add_library(cudf
src/unary/legacy/math_ops.cu
src/unary/legacy/cast_ops.cu
src/unary/legacy/null_ops.cu
src/unary/math_ops.cu
src/io/legacy/cuio_common.cpp
src/io/legacy/io_functions.cpp
src/io/convert/csr/legacy/cudf_to_csr.cu
Expand Down
15 changes: 5 additions & 10 deletions cpp/include/cudf/utilities/legacy/wrapper_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,17 +340,12 @@ using unwrapped_type_t = typename unwrapped_type<T>::type;

} // namespace detail

using category = detail::wrapper<int32_t, GDF_CATEGORY>;

using category = detail::wrapper<int32_t, GDF_CATEGORY>;
using nvstring_category = detail::wrapper<int32_t, GDF_STRING_CATEGORY>;

using timestamp = detail::wrapper<int64_t, GDF_TIMESTAMP>;

using date32 = detail::wrapper<int32_t, GDF_DATE32>;

using date64 = detail::wrapper<int64_t, GDF_DATE64>;

using bool8 = detail::wrapper<int8_t, GDF_BOOL8>;
using timestamp = detail::wrapper<int64_t, GDF_TIMESTAMP>;
using date32 = detail::wrapper<int32_t, GDF_DATE32>;
using date64 = detail::wrapper<int64_t, GDF_DATE64>;
using bool8 = detail::wrapper<int8_t, GDF_BOOL8>;

// This is necessary for global, constant, non-fundamental types
// We can't rely on --expt-relaxed-constexpr here because `bool8` is not a
Expand Down
343 changes: 343 additions & 0 deletions cpp/src/unary/math_ops.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
/*
* Copyright (c) 2019, 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 "unary_ops.cuh"
#include <cudf/legacy/unary.hpp>
#include <cudf/legacy/copying.hpp>

#include <cudf/utilities/type_dispatcher.hpp>
#include <cudf/column/column_factories.hpp>
#include <cudf/copying.hpp>

#include <cmath>
#include <algorithm>
#include <type_traits>

namespace cudf {
namespace experimental {
namespace detail {

// trig functions

struct DeviceSin {
template<typename T>
__device__
T apply(T data) {
return std::sin(data);
jrhemstad marked this conversation as resolved.
Show resolved Hide resolved
}
};

struct DeviceCos {
template<typename T>
__device__
T apply(T data) {
return std::cos(data);
}
};

struct DeviceTan {
template<typename T>
__device__
T apply(T data) {
return std::tan(data);
}
};

struct DeviceArcSin {
template<typename T>
__device__
T apply(T data) {
return std::asin(data);
}
};

struct DeviceArcCos {
template<typename T>
__device__
T apply(T data) {
return std::acos(data);
}
};

struct DeviceArcTan {
template<typename T>
__device__
T apply(T data) {
return std::atan(data);
}
};

// exponential functions

struct DeviceExp {
template<typename T>
__device__
T apply(T data) {
return std::exp(data);
}
};

struct DeviceLog {
template<typename T>
__device__
T apply(T data) {
return std::log(data);
}
};

struct DeviceSqrt {
template<typename T>
__device__
T apply(T data) {
return std::sqrt(data);
}
};

// rounding functions

struct DeviceCeil {
template<typename T>
__device__
T apply(T data) {
return std::ceil(data);
}
};

struct DeviceFloor {
template<typename T>
__device__
T apply(T data) {
return std::floor(data);
}
};

struct DeviceAbs {
template<typename T>
__device__
T apply(T data) {
return std::abs(data);
}
};

// bitwise op

struct DeviceInvert {
// TODO: maybe sfinae overload this for cudf::bool8
template<typename T>
__device__
T apply(T data) {
return ~data;
}
};

// logical op

struct DeviceNot {
template<typename T>
__device__
cudf::bool8 apply(T data) {
return static_cast<cudf::bool8>( !data );
}
};


template<typename T, typename F>
static void launch(cudf::column_view const& input, cudf::mutable_column_view& output) {
cudf::experimental::unary::Launcher<T, T, F>::launch(input, output);
}


template <typename F>
struct MathOpDispatcher {
template <typename T>
typename std::enable_if_t<std::is_arithmetic<T>::value, void>
operator()(cudf::column_view const& input, cudf::mutable_column_view& output) {
launch<T, F>(input, output);
}

template <typename T>
typename std::enable_if_t<!std::is_arithmetic<T>::value, void>
operator()(cudf::column_view const& input, cudf::mutable_column_view& output) {
CUDF_FAIL("Unsupported datatype for operation");
}
};


template <typename F>
struct BitwiseOpDispatcher {
template <typename T>
typename std::enable_if_t<std::is_integral<T>::value, void>
operator()(cudf::column_view const& input, cudf::mutable_column_view& output) {
launch<T, F>(input, output);
}

template <typename T>
typename std::enable_if_t<!std::is_integral<T>::value, void>
operator()(cudf::column_view const& input, cudf::mutable_column_view& output) {
CUDF_FAIL("Unsupported datatype for operation");
}
};


template <typename F>
struct LogicalOpDispatcher {
private:
template <typename T>
static constexpr bool is_supported() {
return std::is_arithmetic<T>::value ||
std::is_same<T, cudf::bool8>::value;

// TODO: try using member detector
// std::is_member_function_pointer<decltype(&T::operator!)>::value;
}

public:
template <typename T>
typename std::enable_if_t<is_supported<T>(), void>
operator()(cudf::column_view const& input, cudf::mutable_column_view& output) {
cudf::experimental::unary::Launcher<T, cudf::bool8, F>::launch(input, output);
}

template <typename T>
typename std::enable_if_t<!is_supported<T>(), void>
operator()(cudf::column_view const& input, cudf::mutable_column_view& output) {
CUDF_FAIL("Unsupported datatype for operation");
}
};

} // namespace detail

std::unique_ptr<cudf::column>
codereport marked this conversation as resolved.
Show resolved Hide resolved
unary_operation(cudf::column_view input,
codereport marked this conversation as resolved.
Show resolved Hide resolved
cudf::unary_op op,
cudaStream_t stream = 0,
rmm::mr::device_memory_resource* mr =
rmm::mr::get_default_resource()) {

std::unique_ptr<cudf::column> output = [&] {
if (op == cudf::unary_op::NOT) {
auto mask_state = input.null_mask() ? cudf::UNINITIALIZED
: cudf::UNALLOCATED;

return cudf::make_numeric_column(cudf::data_type(cudf::BOOL8),
input.size(),
mask_state,
stream,
mr);
} else {
return cudf::experimental::allocate_like(input);
}
} ();

if (input.size() == 0) return output;

auto output_view = output->mutable_view();;

cudf::experimental::unary::handleChecksAndValidity(input, output_view);

switch(op){
case unary_op::SIN:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceSin>{},
input, output_view);
break;
case unary_op::COS:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceCos>{},
input, output_view);
break;
case unary_op::TAN:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceTan>{},
input, output_view);
break;
case unary_op::ARCSIN:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceArcSin>{},
input, output_view);
break;
case unary_op::ARCCOS:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceArcCos>{},
input, output_view);
break;
case unary_op::ARCTAN:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceArcTan>{},
input, output_view);
break;
case unary_op::EXP:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceExp>{},
input, output_view);
break;
case unary_op::LOG:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceLog>{},
input, output_view);
break;
case unary_op::SQRT:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceSqrt>{},
input, output_view);
break;
case unary_op::CEIL:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceCeil>{},
input, output_view);
break;
case unary_op::FLOOR:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceFloor>{},
input, output_view);
break;
case unary_op::ABS:
cudf::experimental::type_dispatcher(
input.type(),
detail::MathOpDispatcher<detail::DeviceAbs>{},
input, output_view);
break;
case unary_op::BIT_INVERT:
cudf::experimental::type_dispatcher(
input.type(),
detail::BitwiseOpDispatcher<detail::DeviceInvert>{},
input, output_view);
break;
case unary_op::NOT:
cudf::experimental::type_dispatcher(
input.type(),
detail::LogicalOpDispatcher<detail::DeviceNot>{},
input, output_view);
break;
default:
CUDF_FAIL("Undefined unary operation");
}
return output;
}

} // namespace experimental
} // namespace cudf
Loading