Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
300e26c
build(simd): add xsimd dependency and simd verification
Alvaro-Kothe May 5, 2026
1022e10
Update pandas/_libs/meson.build
Alvaro-Kothe May 6, 2026
ed588ad
ci: remove no simd job
Alvaro-Kothe May 6, 2026
84a4982
refactor: create arch specific loop
Alvaro-Kothe May 6, 2026
aaf025b
refactor: move configuration set inside main verification
Alvaro-Kothe May 6, 2026
0fefde7
fix: bump xsimd to 14.2 for MSVC ARM support
Alvaro-Kothe May 6, 2026
effdd43
build: remove simd option
Alvaro-Kothe May 8, 2026
af5feeb
perf(moments): add simd instructions with xsimd to reduce moments
Alvaro-Kothe May 2, 2026
5fa4ada
fix: add missing files
Alvaro-Kothe May 5, 2026
6b5f11b
refactor: remove maybe_unused directive
Alvaro-Kothe May 5, 2026
375e012
refactor: use separate files for instantiation
Alvaro-Kothe May 6, 2026
7d01e35
refactor: remove MOMENTS_* macros
Alvaro-Kothe May 6, 2026
5c3956a
fix: bump to c++20 and use optional, span and unlikely
Alvaro-Kothe May 6, 2026
5afecd8
fix: use relative tolerance for assertion
Alvaro-Kothe May 6, 2026
19b0285
refactor: move moments_merge to c++
Alvaro-Kothe May 6, 2026
dc0341f
refactor: change `n` member to `size_t` in `Moments` struct
Alvaro-Kothe May 7, 2026
ed4f066
refactor: organize math expressions
Alvaro-Kothe May 7, 2026
41a4e1a
refactor: remove static from moments_add_valuem
Alvaro-Kothe May 7, 2026
e708151
fix: use result.n in if branch
Alvaro-Kothe May 7, 2026
6b64620
refactor: use auto
Alvaro-Kothe May 7, 2026
9671223
refactor: move subspan outside of function call
Alvaro-Kothe May 7, 2026
0743dd7
refactor: remove step outside of template
Alvaro-Kothe May 7, 2026
974d08f
refactor: use bool for skipna
Alvaro-Kothe May 7, 2026
57bdfd9
refactor: deduplicate #if macro usage
Alvaro-Kothe May 7, 2026
970cd0a
fix: try to fix maybe_unitialized warning
Alvaro-Kothe May 7, 2026
9cda6c0
refactor: mark as external and don't use it
Alvaro-Kothe May 7, 2026
a0e3abb
fix: ensure internal linkage in simd module
Alvaro-Kothe May 9, 2026
eb806f8
perf: use nanoarrow method to pack bits
Alvaro-Kothe May 9, 2026
e92e2d1
refactor: improve naming
Alvaro-Kothe May 10, 2026
1e2ccc0
refactor: increase similarity between moments update functions
Alvaro-Kothe May 10, 2026
8ca9a2c
perf: use simd instructions to handle mask directly
Alvaro-Kothe May 12, 2026
bd2a040
use bitmask
Alvaro-Kothe May 12, 2026
381be60
chore: improve readability
Alvaro-Kothe May 12, 2026
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
29 changes: 29 additions & 0 deletions LICENSES/XSIMD_LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Copyright (c) 2016, Johan Mabille, Sylvain Corlay, Wolf Vollprecht and Martin Renou
Copyright (c) 2016, QuantStack
Copyright (c) 2018, Serge Guelton
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6 changes: 4 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ project(
default_options: [
'buildtype=release',
'c_std=c17',
'cpp_std=c++17',
'cpp_std=c++20',
'warning_level=2',
],
)
Expand All @@ -37,15 +37,17 @@ add_project_arguments(
)

cc = meson.get_compiler('c')
cxx = meson.get_compiler('cpp')
if cc.get_id() == 'msvc'
# Tracking issue: https://github.com/pandas-dev/pandas/issues/63701
# Ignore some MSVC specific warnings:
# C4244: possible loss of data in conversion. Reproductible with `-Wconversion`.
# C4267: conversion from `size_t` to smaller type.
# C4551: occurs due to Cython generating code with (void)func.
# https://github.com/cython/cython/issues/3579
# C4146: unary minus operator applied to unsigned type. Occurs in xsimd.
add_project_arguments(
['/wd4244', '/wd4267', '/wd4551'],
['/wd4244', '/wd4267', '/wd4551', '/wd4146'],
language: ['c', 'cpp'],
)
endif
Expand Down
18 changes: 18 additions & 0 deletions pandas/_libs/algos.pxd
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
cimport cython
from cython cimport size_t
from libc.math cimport (
NAN,
sqrt,
)
from numpy cimport (
float64_t,
int64_t,
uint8_t,
)

from pandas._libs.dtypes cimport (
Expand Down Expand Up @@ -50,6 +52,22 @@ cdef inline void moments_add_value(
mean[0] += delta_n


cdef extern from "pandas/moments.h":
ctypedef struct Moments:
float64_t mean
float64_t m2
float64_t m3
float64_t m4
size_t n

Moments moments_reduce(
const double *values,
size_t n,
bint skipna,
const uint8_t *mask,
int max_moment) noexcept nogil


@cython.cdivision(True)
cdef inline float64_t calc_skew(
int64_t nobs, float64_t m2, float64_t m3
Expand Down
35 changes: 19 additions & 16 deletions pandas/_libs/algos.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1603,9 +1603,9 @@ def diff_2d(
@cython.boundscheck(False)
@cython.wraparound(False)
cdef void accumulate_moments_scalar(
const float64_t[:] values,
const float64_t[::1] values,
bint skipna,
const uint8_t[:] mask,
const uint8_t[::1] mask,
int64_t* nobs,
float64_t* mean,
float64_t* m2,
Expand All @@ -1614,17 +1614,20 @@ cdef void accumulate_moments_scalar(
int max_moment,
) noexcept nogil:
cdef:
Py_ssize_t i, n = len(values)
bint uses_mask = mask is not None
float64_t val
Moments moments
const float64_t* values_ptr = &values[0]
const uint8_t* mask_ptr = &mask[0] if mask is not None else NULL
size_t n = <size_t>values.shape[0]

for i in range(n):
val = values[i]
if uses_mask and mask[i]:
val = NaN
if skipna and isnan(val):
continue
moments_add_value(val, nobs, mean, m2, m3, m4, max_moment)
moments = moments_reduce(values_ptr, n, skipna, mask_ptr, max_moment)
if max_moment >= 4:
m4[0] = moments.m4
if max_moment >= 3:
m3[0] = moments.m3

m2[0] = moments.m2
mean[0] = moments.mean
nobs[0] = <int64_t>moments.n


@cython.boundscheck(False)
Expand Down Expand Up @@ -1676,9 +1679,9 @@ cdef void accumulate_moments_axis(
@cython.boundscheck(False)
@cython.wraparound(False)
def scalar_skew(
const float64_t[:] values,
const float64_t[::1] values,
bint skipna,
const uint8_t[:] mask,
const uint8_t[::1] mask,
) -> float:
cdef:
int64_t nobs = 0
Expand All @@ -1693,9 +1696,9 @@ def scalar_skew(
@cython.boundscheck(False)
@cython.wraparound(False)
def scalar_kurt(
const float64_t[:] values,
const float64_t[::1] values,
bint skipna,
const uint8_t[:] mask,
const uint8_t[::1] mask,
) -> float:
cdef:
int64_t nobs = 0
Expand Down
33 changes: 33 additions & 0 deletions pandas/_libs/include/pandas/moments.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright (c) 2026, PyData Development Team
All rights reserved.

Distributed under the terms of the BSD Simplified License.

The full license is in the LICENSE file, distributed with this software.
*/

#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
double mean;
double m2;
double m3;
double m4;
size_t n;
} Moments;

/// Compute central moments until `max_moment` using `n` elements from `values`.
Moments moments_reduce(const double *values, size_t n, bool skipna,
const uint8_t *mask, int max_moment);
#ifdef __cplusplus
}
#endif
Loading
Loading