Skip to content

REF: Use more conditional nogil & const memoryviews #60955

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

Merged
merged 5 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 1 addition & 27 deletions pandas/_libs/algos.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -818,33 +818,7 @@ def is_monotonic(const numeric_object_t[:] arr, bint timelike):
if timelike and <int64_t>arr[0] == NPY_NAT:
return False, False, False

if numeric_object_t is not object:
with nogil:
prev = arr[0]
for i in range(1, n):
cur = arr[i]
if timelike and <int64_t>cur == NPY_NAT:
is_monotonic_inc = 0
is_monotonic_dec = 0
break
if cur < prev:
is_monotonic_inc = 0
elif cur > prev:
is_monotonic_dec = 0
elif cur == prev:
is_unique = 0
else:
# cur or prev is NaN
is_monotonic_inc = 0
is_monotonic_dec = 0
break
if not is_monotonic_inc and not is_monotonic_dec:
is_monotonic_inc = 0
is_monotonic_dec = 0
break
prev = cur
else:
# object-dtype, identical to above except we cannot use `with nogil`
with nogil(numeric_object_t is not object):
prev = arr[0]
for i in range(1, n):
cur = arr[i]
Expand Down
15 changes: 1 addition & 14 deletions pandas/_libs/hashtable_func_helper.pxi.in
Original file line number Diff line number Diff line change
Expand Up @@ -415,20 +415,7 @@ def mode(ndarray[htfunc_t] values, bint dropna, const uint8_t[:] mask=None):

modes = np.empty(nkeys, dtype=values.dtype)

if htfunc_t is not object:
with nogil:
for k in range(nkeys):
count = counts[k]
if count == max_count:
j += 1
elif count > max_count:
max_count = count
j = 0
else:
continue

modes[j] = keys[k]
else:
with nogil(htfunc_t is not object):
for k in range(nkeys):
count = counts[k]
if count == max_count:
Expand Down
6 changes: 3 additions & 3 deletions pandas/_libs/internals.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ def get_concat_blkno_indexers(list blknos_list not None):
@cython.boundscheck(False)
@cython.wraparound(False)
def get_blkno_indexers(
int64_t[:] blknos, bint group=True
const int64_t[:] blknos, bint group=True
) -> list[tuple[int, slice | np.ndarray]]:
"""
Enumerate contiguous runs of integers in ndarray.
Expand Down Expand Up @@ -596,8 +596,8 @@ def get_blkno_placements(blknos, group: bool = True):
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef update_blklocs_and_blknos(
ndarray[intp_t, ndim=1] blklocs,
ndarray[intp_t, ndim=1] blknos,
const intp_t[:] blklocs,
const intp_t[:] blknos,
Py_ssize_t loc,
intp_t nblocks,
):
Expand Down
17 changes: 10 additions & 7 deletions pandas/_libs/join.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,10 @@ def full_outer_join(const intp_t[:] left, const intp_t[:] right,

@cython.wraparound(False)
@cython.boundscheck(False)
cdef void _get_result_indexer(intp_t[::1] sorter, intp_t[::1] indexer) noexcept nogil:
cdef void _get_result_indexer(
const intp_t[::1] sorter,
intp_t[::1] indexer,
) noexcept nogil:
"""NOTE: overwrites indexer with the result to avoid allocating another array"""
cdef:
Py_ssize_t i, n, idx
Expand Down Expand Up @@ -681,8 +684,8 @@ def outer_join_indexer(ndarray[numeric_object_t] left, ndarray[numeric_object_t]
from pandas._libs.hashtable cimport Int64HashTable


def asof_join_backward_on_X_by_Y(ndarray[numeric_t] left_values,
ndarray[numeric_t] right_values,
def asof_join_backward_on_X_by_Y(const numeric_t[:] left_values,
const numeric_t[:] right_values,
const int64_t[:] left_by_values,
const int64_t[:] right_by_values,
bint allow_exact_matches=True,
Expand Down Expand Up @@ -752,8 +755,8 @@ def asof_join_backward_on_X_by_Y(ndarray[numeric_t] left_values,
return left_indexer, right_indexer


def asof_join_forward_on_X_by_Y(ndarray[numeric_t] left_values,
ndarray[numeric_t] right_values,
def asof_join_forward_on_X_by_Y(const numeric_t[:] left_values,
const numeric_t[:] right_values,
const int64_t[:] left_by_values,
const int64_t[:] right_by_values,
bint allow_exact_matches=1,
Expand Down Expand Up @@ -824,8 +827,8 @@ def asof_join_forward_on_X_by_Y(ndarray[numeric_t] left_values,
return left_indexer, right_indexer


def asof_join_nearest_on_X_by_Y(ndarray[numeric_t] left_values,
ndarray[numeric_t] right_values,
def asof_join_nearest_on_X_by_Y(const numeric_t[:] left_values,
const numeric_t[:] right_values,
const int64_t[:] left_by_values,
const int64_t[:] right_by_values,
bint allow_exact_matches=True,
Expand Down
6 changes: 2 additions & 4 deletions pandas/_libs/lib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -981,16 +981,14 @@ def get_level_sorter(

@cython.boundscheck(False)
@cython.wraparound(False)
def count_level_2d(ndarray[uint8_t, ndim=2, cast=True] mask,
def count_level_2d(const uint8_t[:, :] mask,
const intp_t[:] labels,
Py_ssize_t max_bin,
):
cdef:
Py_ssize_t i, j, k, n
Py_ssize_t i, j, k = mask.shape[1], n = mask.shape[0]
ndarray[int64_t, ndim=2] counts

n, k = (<object>mask).shape

counts = np.zeros((n, max_bin), dtype="i8")
with nogil:
for i in range(n):
Expand Down
22 changes: 1 addition & 21 deletions pandas/_libs/reshape.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,7 @@ def unstack(const numeric_object_t[:, :] values, const uint8_t[:] mask,
cdef:
Py_ssize_t i, j, w, nulls, s, offset

if numeric_object_t is not object:
# evaluated at compile-time
with nogil:
for i in range(stride):

nulls = 0
for j in range(length):

for w in range(width):

offset = j * width + w

if mask[offset]:
s = i * width + w
new_values[j, s] = values[offset - nulls, i]
new_mask[j, s] = 1
else:
nulls += 1

else:
# object-dtype, identical to above but we cannot use nogil
with nogil(numeric_object_t is not object):
for i in range(stride):

nulls = 0
Expand Down