Skip to content

Commit

Permalink
Migrate round to pylibcudf (#15863)
Browse files Browse the repository at this point in the history
xref #15162

Migrate round.pxd to use pylibcudf APIs.

Authors:
  - Thomas Li (https://github.com/lithomas1)

Approvers:
  - https://github.com/brandon-b-miller
  - Lawrence Mitchell (https://github.com/wence-)

URL: #15863
  • Loading branch information
lithomas1 authored May 31, 2024
1 parent dec0354 commit e7be142
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 27 deletions.
1 change: 1 addition & 0 deletions docs/cudf/source/user_guide/api_docs/pylibcudf/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This page provides API documentation for pylibcudf.
reduce
reshape
rolling
round
scalar
search
stream_compaction
Expand Down
6 changes: 6 additions & 0 deletions docs/cudf/source/user_guide/api_docs/pylibcudf/round.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
=====
round
=====

.. automodule:: cudf._lib.pylibcudf.round
:members:
1 change: 1 addition & 0 deletions python/cudf/cudf/_lib/pylibcudf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(cython_sources
replace.pyx
reshape.pyx
rolling.pyx
round.pyx
scalar.pyx
search.pyx
stream_compaction.pyx
Expand Down
2 changes: 2 additions & 0 deletions python/cudf/cudf/_lib/pylibcudf/__init__.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ from . cimport (
replace,
reshape,
rolling,
round,
search,
sorting,
stream_compaction,
Expand Down Expand Up @@ -48,6 +49,7 @@ __all__ = [
"reduce",
"replace",
"rolling",
"round",
"search",
"stream_compaction",
"strings",
Expand Down
2 changes: 2 additions & 0 deletions python/cudf/cudf/_lib/pylibcudf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
replace,
reshape,
rolling,
round,
search,
sorting,
stream_compaction,
Expand Down Expand Up @@ -48,6 +49,7 @@
"reduce",
"replace",
"rolling",
"round",
"search",
"stream_compaction",
"strings",
Expand Down
2 changes: 1 addition & 1 deletion python/cudf/cudf/_lib/pylibcudf/libcudf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# the License.
# =============================================================================

set(cython_sources aggregation.pyx binaryop.pyx copying.pyx replace.pyx reduce.pxd
set(cython_sources aggregation.pyx binaryop.pyx copying.pyx replace.pyx reduce.pxd round.pyx
stream_compaction.pyx types.pyx unary.pyx
)

Expand Down
6 changes: 3 additions & 3 deletions python/cudf/cudf/_lib/pylibcudf/libcudf/round.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ from cudf._lib.pylibcudf.libcudf.column.column_view cimport column_view

cdef extern from "cudf/round.hpp" namespace "cudf" nogil:

ctypedef enum rounding_method "cudf::rounding_method":
HALF_UP "cudf::rounding_method::HALF_UP"
HALF_EVEN "cudf::rounding_method::HALF_EVEN"
cpdef enum class rounding_method(int32_t):
HALF_UP
HALF_EVEN

cdef unique_ptr[column] round (
const column_view& input,
Expand Down
Empty file.
13 changes: 13 additions & 0 deletions python/cudf/cudf/_lib/pylibcudf/round.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2024, NVIDIA CORPORATION.
from libc.stdint cimport int32_t

from cudf._lib.pylibcudf.libcudf.round cimport rounding_method

from .column cimport Column


cpdef Column round(
Column source,
int32_t decimal_places = *,
rounding_method round_method = *
)
54 changes: 54 additions & 0 deletions python/cudf/cudf/_lib/pylibcudf/round.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (c) 2024, NVIDIA CORPORATION.
from libc.stdint cimport int32_t
from libcpp.memory cimport unique_ptr
from libcpp.utility cimport move

from cudf._lib.pylibcudf.libcudf.round cimport (
round as cpp_round,
rounding_method,
)

from cudf._lib.pylibcudf.libcudf.round import \
rounding_method as RoundingMethod # no-cython-lint

from cudf._lib.pylibcudf.libcudf.column.column cimport column

from .column cimport Column


cpdef Column round(
Column source,
int32_t decimal_places = 0,
rounding_method round_method = rounding_method.HALF_UP
):
"""Rounds all the values in a column to the specified number of decimal places.
For details, see :cpp:func:`round`.
Parameters
----------
source : Column
The Column for which to round values.
decimal_places: int32_t, optional
The number of decimal places to round to (default 0)
round_method: rounding_method, optional
The method by which to round each value.
Can be one of { RoundingMethod.HALF_UP, RoundingMethod.HALF_EVEN }
(default rounding_method.HALF_UP)
Returns
-------
pylibcudf.Column
A Column with values rounded
"""
cdef unique_ptr[column] c_result
with nogil:
c_result = move(
cpp_round(
source.view(),
decimal_places,
round_method
)
)

return Column.from_libcudf(move(c_result))
36 changes: 13 additions & 23 deletions python/cudf/cudf/_lib/round.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,10 @@

from cudf.core.buffer import acquire_spill_lock

from libcpp.memory cimport unique_ptr
from libcpp.utility cimport move

from cudf._lib.column cimport Column
from cudf._lib.pylibcudf.libcudf.column.column cimport column
from cudf._lib.pylibcudf.libcudf.column.column_view cimport column_view
from cudf._lib.pylibcudf.libcudf.round cimport (
round as cpp_round,
rounding_method as cpp_rounding_method,
)

import cudf._lib.pylibcudf as plc
from cudf._lib.pylibcudf.round import RoundingMethod


@acquire_spill_lock()
Expand All @@ -31,19 +25,15 @@ def round(Column input_col, int decimal_places=0, how="half_even"):
if how not in {"half_even", "half_up"}:
raise ValueError("'how' must be either 'half_even' or 'half_up'")

cdef column_view input_col_view = input_col.view()
cdef unique_ptr[column] c_result
cdef cpp_rounding_method c_how = (
cpp_rounding_method.HALF_EVEN if how == "half_even"
else cpp_rounding_method.HALF_UP
how = (
RoundingMethod.HALF_EVEN if how == "half_even"
else RoundingMethod.HALF_UP
)
with nogil:
c_result = move(
cpp_round(
input_col_view,
decimal_places,
c_how
)
)

return Column.from_unique_ptr(move(c_result))
return Column.from_pylibcudf(
plc.round.round(
input_col.to_pylibcudf(mode="read"),
decimal_places,
how
)
)
38 changes: 38 additions & 0 deletions python/cudf/cudf/pylibcudf_tests/test_round.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright (c) 2024, NVIDIA CORPORATION.

import pyarrow as pa
import pytest
from utils import assert_column_eq

import cudf._lib.pylibcudf as plc


@pytest.fixture(params=[False, True])
def nullable(request):
return request.param


@pytest.fixture(params=["float32", "float64"])
def column(request, nullable):
values = [2.5, 2.49, 1.6, 8, -1.5, -1.7, -0.5, 0.5]
typ = {"float32": pa.float32(), "float64": pa.float64()}[request.param]
if nullable:
values[2] = None
return plc.interop.from_arrow(pa.array(values, type=typ))


@pytest.mark.parametrize(
"round_mode", ["half_towards_infinity", "half_to_even"]
)
@pytest.mark.parametrize("decimals", [0, 1, 2, 5])
def test_round(column, round_mode, decimals):
method = {
"half_towards_infinity": plc.round.RoundingMethod.HALF_UP,
"half_to_even": plc.round.RoundingMethod.HALF_EVEN,
}[round_mode]
got = plc.round.round(column, decimals, method)
expect = pa.compute.round(
plc.interop.to_arrow(column), decimals, round_mode
)

assert_column_eq(expect, got)

0 comments on commit e7be142

Please sign in to comment.