ronantakizawa/codereview-bench huggingface dataset:
Repository: scipy/scipy
File: scipy/sparse/sparsetools/dia.h (C/C++)

Code before:
 *
 */
template <class I, class T>
I dia_tocsr(const I n_rows,
            const I n_cols,
            const I n_diags,
            const I L,
            const I offsets[],
            const T data[],
            const I order[],
                  T csr_data[],
                  I indices[],
                  I indptr[])
{
    const I j_end = min(L, n_cols); // columns limit
    indptr[0] = 0;
    I nnz = 0;
    // loop over rows
    for (I i = 0; i < n_rows; ++i) {
        // loop over offsets in ascending order
        for (I k = 0; k < n_diags; ++k) {
            const I n = order[k], // index of diagonal
                    j = i + offsets[n]; // column
            if (j < 0 or j >= j_end)
                continue;
            const T x = (data + npy_intp(L) * n)[j];
            if (x != 0) {
                indices[nnz] = j;
                csr_data[nnz] = x;
                ++nnz;
            }
        }
        indptr[1 + i] = nnz;
    }
    return nnz; // actual output lengths
}


#endif


Review comment (suggestion):
Let's use a different indexing expression here, to be more consistent with the rest of the usages in sparsetools:

```
data[L*n + j]
```

Code after:
 *
 */
template <class I, class T>
I dia_tocsr(const I n_rows,
            const I n_cols,
            const I n_diags,
            const I L,
            const I offsets[],
            const T data[],
            const I order[],
                  T csr_data[],
                  I indices[],
                  I indptr[])
{
    const I j_end = min(L, n_cols); // columns limit
    indptr[0] = 0;
    I nnz = 0;
    // loop over rows
    for (I i = 0; i < n_rows; ++i) {
        // loop over offsets in ascending order
        for (I k = 0; k < n_diags; ++k) {
            const I n = order[k], // index of diagonal
                    j = i + offsets[n]; // column
            if (j < 0 or j >= j_end)
                continue;
            const T x = data[npy_intp(L) * n + j];
            if (x != 0) {
                indices[nnz] = j;
                csr_data[nnz] = x;
                ++nnz;
            }
        }
        indptr[1 + i] = nnz;
    }
    return nnz; // actual output lengths
}


#endif
Repository: scipy/scipy
File: tools/wheels/repair_windows.sh (Shell)

Code before:
set -xe

WHEEL="$1"
DEST_DIR="$2"
OPENBLAS_DIR=$(python -c"import scipy_openblas32 as sop; print(sop.get_lib_dir())")

# Determine the strip command based on TARGET_ARCH
# TARGET_ARCH should be set by the CI environment (e.g., ARM64, AMD64)
TARGET_ARCH="${TARGET_ARCH:-}" # Default to empty string if not set
STRIP_COMMAND="strip"
if [ "$TARGET_ARCH" = "ARM64" ]; then
  STRIP_COMMAND="llvm-strip"
  echo "Using llvm-strip for ARM64 target."
else
  echo "Using default strip command."
fi

# create a temporary directory in the destination folder and unpack the wheel
# into there
pushd $DEST_DIR
mkdir -p tmp
pushd tmp
wheel unpack $WHEEL
pushd scipy*

# To avoid DLL hell, the file name of libopenblas that's being vendored with
# the wheel has to be name-mangled. delvewheel is unable to name-mangle PYD
# containing extra data at the end of the binary, which frequently occurs when
# building with mingw.
# We therefore find each PYD in the directory structure and strip them.

for f in $(find ./scipy* -name '*.pyd'); do $STRIP_COMMAND $f; done

# now repack the wheel and overwrite the original
wheel pack .
mv -fv *.whl $WHEEL

cd $DEST_DIR

Review comment (bug):
Are you able to check locally whether this stripping actually changes anything? IIRC the only reason we have it is because `mingw-w64` is leaving (or used to leave) some bad content at the end of each `.pyd` file. For LLVM-based compilers, this may well do nothing, since we're not building with debug info or anything like that.

Code after:
set -xe

WHEEL="$1"
DEST_DIR="$2"
OPENBLAS_DIR=$(python -c"import scipy_openblas32 as sop; print(sop.get_lib_dir())")

# Skip the strip command based on TARGET_ARCH
# TARGET_ARCH should be set by the CI environment (e.g., ARM64, AMD64)
TARGET_ARCH="${TARGET_ARCH:-}" # Default to empty string if not set

if [ "$TARGET_ARCH" = "ARM64" ]; then
  echo "Skipping stripping for ARM64 target."
else
  echo "Performing stripping for AMD64 target."

  # create a temporary directory in the destination folder and unpack the wheel
  # into there
  pushd $DEST_DIR
  mkdir -p tmp
  pushd tmp
  wheel unpack $WHEEL
  pushd scipy*

  # To avoid DLL hell, the file name of libopenblas that's being vendored with
  # the wheel has to be name-mangled. delvewheel is unable to name-mangle PYD
  # containing extra data at the end of the binary, which frequently occurs when
  # building with mingw.
  # We therefore find each PYD in the directory structure and strip them.

  for f in $(find ./scipy* -name '*.pyd'); do strip $f; done

  # now repack the wheel and overwrite the original
  wheel pack .
  mv -fv *.whl $WHEEL

  cd $DEST_DIR
  rm -rf tmp
fi
Repository: scipy/scipy
File: scipy/conftest.py (Python)

Code before:
# Pytest customization
import json
import multiprocessing
import os
import warnings
import tempfile
from contextlib import contextmanager
from typing import Literal

import numpy as np
import pytest
import hypothesis

from scipy._lib._fpumode import get_fpu_mode
from scipy._lib._array_api import (
    SCIPY_ARRAY_API, SCIPY_DEVICE, array_namespace, default_xp,
    is_cupy, is_dask, is_jax, is_torch,
)
from scipy._lib._testutils import FPUModeChangeWarning
from scipy._lib.array_api_extra.testing import patch_lazy_xp_functions
from scipy._lib import _pep440

try:
    from scipy_doctest.conftest import dt_config
    HAVE_SCPDT = True
except ModuleNotFoundError:
    HAVE_SCPDT = False

try:

Review comment (suggestion):
```suggestion
import multiprocessing
import os
import sys
```

Code after:
# Pytest customization
import json
import multiprocessing
import os
import sys
import warnings
import tempfile
from contextlib import contextmanager
from typing import Literal

import numpy as np
import pytest
import hypothesis

from scipy._lib._fpumode import get_fpu_mode
from scipy._lib._array_api import (
    SCIPY_ARRAY_API, SCIPY_DEVICE, array_namespace, default_xp,
    is_cupy, is_dask, is_jax, is_torch,
)
from scipy._lib._testutils import FPUModeChangeWarning
from scipy._lib.array_api_extra.testing import patch_lazy_xp_functions
from scipy._lib import _pep440

try:
    from scipy_doctest.conftest import dt_config
    HAVE_SCPDT = True
except ModuleNotFoundError:
    HAVE_SCPDT = False
Repository: scipy/scipy
File: scipy/_lib/_array_api.py (Python)

Code before:

    Parameters
    ----------
    func : Callable
        Function to be tested. It must be decorated with ``@xp_capabilities``.
    *args : Any, optional
        Extra pytest parameters for the use case, e.g.::

        @pytest.mark.parametrize("func,verb", [
            make_xp_pytest_param(f1, "hello"),
            make_xp_pytest_param(f2, "world")])
        def test(func, verb, xp):
            # iterates on (func=f1, verb="hello")
            # and (func=f2, verb="world")

    See Also
    --------
    xp_capabilities
    make_xp_test_case
    array_api_extra.testing.lazy_xp_function
    """
    import pytest

    marks = _make_xp_pytest_marks(func, capabilities_table=capabilities_table)
    return pytest.param(func, *args, marks=marks, id=func.__name__)


# Is it OK to have a dictionary that is mutated (once upon import) in many places?
xp_capabilities_table = {}  # type: ignore[var-annotated]


Review comment (suggestion):
Moved the function for ease of reading, made public, and added documentation.
Implementation has not been changed.

Code after:
    func : Callable
        Function to be tested. It must be decorated with ``@xp_capabilities``.
    *args : Any, optional
        Extra pytest parameters for the use case, e.g.::

        @pytest.mark.parametrize("func,verb", [
            make_xp_pytest_param(f1, "hello"),
            make_xp_pytest_param(f2, "world")])
        def test(func, verb, xp):
            # iterates on (func=f1, verb="hello")
            # and (func=f2, verb="world")

    See Also
    --------
    xp_capabilities
    make_xp_test_case
    make_xp_pytest_marks
    array_api_extra.testing.lazy_xp_function
    """
    import pytest

    marks = make_xp_pytest_marks(func, capabilities_table=capabilities_table)
    return pytest.param(func, *args, marks=marks, id=func.__name__)


def make_xp_pytest_marks(*funcs, capabilities_table=None):
    """Variant of ``make_xp_test_case`` that returns a list of pytest marks,
    which can be used with the module-level `pytestmark = ...` variable::

        pytestmark = make_xp_pytest_marks(f1, f2)

        def test(xp):
            ...

    In this example, the whole test module is dedicated to testing `f1` or `f2`,
    and the two functions have the same capabilities, so it's unnecessary to
    cherry-pick which test tests which function.
    The above is equivalent to::

        pytestmark = [
            pytest.mark.skip_xp_backends(...),
            pytest.mark.xfail_xp_backends(...), ...]),
        ]

        def test(xp):
            ...
    
    See Also
    --------
    xp_capabilities
    make_xp_test_case
Repository: scipy/scipy
File: scipy/stats/tests/test_marray.py (Python)

Code before:
import pytest
from scipy import stats

from scipy._lib._array_api import xp_assert_close, xp_assert_equal, _length_nonmasked
from scipy._lib.array_api_compat import numpy as np
from scipy.stats._stats_py import _xp_mean, _xp_var
from scipy.stats._axis_nan_policy import _axis_nan_policy_factory


marray = pytest.importorskip('marray')
skip_backend = pytest.mark.skip_xp_backends


def get_arrays(n_arrays, *, dtype='float64', xp=np, shape=(7, 8), seed=84912165484321):
    mxp = marray._get_namespace(xp)
    rng = np.random.default_rng(seed)

    datas, masks = [], []
    for i in range(n_arrays):
        data = rng.random(size=shape)
        if dtype.startswith('complex'):
            data = 10*data * 10j*rng.standard_normal(size=shape)
        data = data.astype(dtype)
        datas.append(data)
        mask = rng.random(size=shape) > 0.75
        masks.append(mask)

    marrays = []
    nan_arrays = []
    for array, mask in zip(datas, masks):

Review comment (bug):
@mdhaber should this be necessary for `marray`? What went wrong without this @steppi ?

Code after:
import numpy as np
import pytest
from scipy import stats
from packaging import version

from scipy._lib._array_api import xp_assert_close, xp_assert_equal, _length_nonmasked
from scipy._lib._array_api import make_xp_pytest_param, make_xp_test_case
from scipy._lib._array_api import SCIPY_ARRAY_API
from scipy.stats._stats_py import _xp_mean, _xp_var
from scipy.stats._axis_nan_policy import _axis_nan_policy_factory


marray = pytest.importorskip('marray')
pytestmark = [
    pytest.mark.skipif(
        not SCIPY_ARRAY_API,
        reason=(
            "special function dispatch to marray required for these tests"
            " is hidden behind SCIPY_ARRAY_API flag."
        ),
    ),
    pytest.mark.skip_xp_backends(
        "array_api_strict",
        reason="scipy/#23412",
    ),
]

skip_backend = pytest.mark.skip_xp_backends

def get_arrays(n_arrays, *, dtype='float64', xp=np, shape=(7, 8), seed=84912165484321):
Repository: scipy/scipy
File: scipy/_lib/src/ccallback.h (C/C++)

Code before:

static void *ccallback__get_thread_local(void)
{
    return PyThread_tss_get(&ccallback_tss_key);
}

static int ccallback__set_thread_local(void *value)
{
    if (!PyThread_tss_is_created(&ccallback_tss_key)) {
        if (PyThread_tss_create(&ccallback_tss_key) != 0) {
            Py_FatalError("scipy.ccallback: TLS Failed to create thread local key");
        }
    }
    return PyThread_tss_set(&ccallback_tss_key, value);
}

/*
 * Obtain a pointer to the current ccallback_t structure.
 */
static ccallback_t *ccallback_obtain(void)
{
    return (ccallback_t *)ccallback__get_thread_local();
}


/*
 * Set Python error status indicating a signature mismatch.
 *
 * Parameters
 * ----------
 * signatures
 *     NULL terminated list of allowed signatures.
 * capsule_signature
 *     The mismatcing signature from user-provided PyCapsule.
 */
static void ccallback__err_invalid_signature(ccallback_signature_t *signatures,
                                             const char *capsule_signature)
{
    PyObject *sig_list = NULL;
    ccallback_signature_t *sig;

    sig_list = PyList_New(0);
    if (sig_list == NULL) {
        return;
    }

    if (capsule_signature == NULL) {
        capsule_signature = "NULL";
    }

    for (sig = signatures; sig->signature != NULL; ++sig) {

Review comment (suggestion):
It looks like this fallback can indeed be removed, since `SCIPY_TLS_EMPTY` is never defined, and I cannot find any external usages nor issues mentioning it.

Code after:

static void *ccallback__get_thread_local(void)
{
    return (void *)_active_ccallback;
}

static int ccallback__set_thread_local(void *value)
{
    _active_ccallback = value;
    return 0;
}

/*
 * Obtain a pointer to the current ccallback_t structure.
 */
static ccallback_t *ccallback_obtain(void)
{
    return (ccallback_t *)ccallback__get_thread_local();
}

/*
 * Set Python error status indicating a signature mismatch.
 *
 * Parameters
 * ----------
 * signatures
 *     NULL terminated list of allowed signatures.
 * capsule_signature
 *     The mismatcing signature from user-provided PyCapsule.
 */
static void ccallback__err_invalid_signature(ccallback_signature_t *signatures,
                                             const char *capsule_signature)
{
    PyObject *sig_list = NULL;
    ccallback_signature_t *sig;

    sig_list = PyList_New(0);
    if (sig_list == NULL) {
        return;
    }

    if (capsule_signature == NULL) {
        capsule_signature = "NULL";
    }

    for (sig = signatures; sig->signature != NULL; ++sig) {
        PyObject *str;
        int ret;

        str = PyUnicode_FromString(sig->signature);
        if (str == NULL) {
Repository: scipy/scipy
File: scipy/linalg/_procrustes.py (Python)

Code before:
"""
Solve the orthogonal Procrustes problem.

"""

from scipy._lib._util import _apply_over_batch
from ._decomp_svd import svd
from scipy._lib._array_api import array_namespace, xp_capabilities, _asarray, is_numpy


__all__ = ['orthogonal_procrustes']


@xp_capabilities()
@_apply_over_batch(('A', 2), ('B', 2))
def orthogonal_procrustes(A, B, check_finite=True):
    """
    Compute the matrix solution of the orthogonal (or unitary) Procrustes problem.

    Given matrices `A` and `B` of the same shape, find an orthogonal (or unitary in
    the case of complex input) matrix `R` that most closely maps `A` to `B` using the
    algorithm given in [1]_.

    Parameters
    ----------
    A : (M, N) array_like
        Matrix to be mapped.
    B : (M, N) array_like
        Target matrix.
    check_finite : bool, optional
        Whether to check that the input matrices contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
    R : (N, N) ndarray
        The matrix solution of the orthogonal Procrustes problem.
        Minimizes the Frobenius norm of ``(A @ R) - B``, subject to

Review comment (suggestion):
```suggestion
@xp_capabilities(jax_jit=False)
```

Code after:
"""
Solve the orthogonal Procrustes problem.

"""

from scipy._lib._util import _apply_over_batch
from ._decomp_svd import svd
from scipy._lib._array_api import array_namespace, xp_capabilities, _asarray, is_numpy


__all__ = ['orthogonal_procrustes']


@xp_capabilities(
    jax_jit=False,
    skip_backends=[("dask.array", "full_matrices=True is not supported by dask")],
)
@_apply_over_batch(('A', 2), ('B', 2))
def orthogonal_procrustes(A, B, check_finite=True):
    """
    Compute the matrix solution of the orthogonal (or unitary) Procrustes problem.

    Given matrices `A` and `B` of the same shape, find an orthogonal (or unitary in
    the case of complex input) matrix `R` that most closely maps `A` to `B` using the
    algorithm given in [1]_.

    Parameters
    ----------
    A : (M, N) array_like
        Matrix to be mapped.
    B : (M, N) array_like
        Target matrix.
    check_finite : bool, optional
        Whether to check that the input matrices contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
Repository: scipy/scipy
File: scipy/linalg/_procrustes.py (Python)

Code before:
"""
Solve the orthogonal Procrustes problem.

"""

from scipy._lib._util import _apply_over_batch
from ._decomp_svd import svd
from scipy._lib._array_api import array_namespace, xp_capabilities, _asarray, is_numpy


__all__ = ['orthogonal_procrustes']


@xp_capabilities(jax_jit=False)
@_apply_over_batch(('A', 2), ('B', 2))
def orthogonal_procrustes(A, B, check_finite=True):
    """
    Compute the matrix solution of the orthogonal (or unitary) Procrustes problem.

    Given matrices `A` and `B` of the same shape, find an orthogonal (or unitary in
    the case of complex input) matrix `R` that most closely maps `A` to `B` using the
    algorithm given in [1]_.

    Parameters
    ----------
    A : (M, N) array_like
        Matrix to be mapped.
    B : (M, N) array_like
        Target matrix.
    check_finite : bool, optional
        Whether to check that the input matrices contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
    R : (N, N) ndarray
        The matrix solution of the orthogonal Procrustes problem.
        Minimizes the Frobenius norm of ``(A @ R) - B``, subject to

Review comment (suggestion):
```suggestion
@xp_capabilities(jax_jit=False, allow_dask_compute=1)
```

Code after:
"""
Solve the orthogonal Procrustes problem.

"""

from scipy._lib._util import _apply_over_batch
from ._decomp_svd import svd
from scipy._lib._array_api import array_namespace, xp_capabilities, _asarray, is_numpy


__all__ = ['orthogonal_procrustes']


@xp_capabilities(
    jax_jit=False,
    skip_backends=[("dask.array", "full_matrices=True is not supported by dask")],
)
@_apply_over_batch(('A', 2), ('B', 2))
def orthogonal_procrustes(A, B, check_finite=True):
    """
    Compute the matrix solution of the orthogonal (or unitary) Procrustes problem.

    Given matrices `A` and `B` of the same shape, find an orthogonal (or unitary in
    the case of complex input) matrix `R` that most closely maps `A` to `B` using the
    algorithm given in [1]_.

    Parameters
    ----------
    A : (M, N) array_like
        Matrix to be mapped.
    B : (M, N) array_like
        Target matrix.
    check_finite : bool, optional
        Whether to check that the input matrices contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
Repository: scipy/scipy
File: scipy/linalg/_procrustes.py (Python)

Code before:
"""
Solve the orthogonal Procrustes problem.

"""

from scipy._lib._util import _apply_over_batch
from ._decomp_svd import svd
from scipy._lib._array_api import array_namespace, xp_capabilities, _asarray, is_numpy


__all__ = ['orthogonal_procrustes']


@xp_capabilities(jax_jit=False, allow_dask_compute=1)
@_apply_over_batch(('A', 2), ('B', 2))
def orthogonal_procrustes(A, B, check_finite=True):
    """
    Compute the matrix solution of the orthogonal (or unitary) Procrustes problem.

    Given matrices `A` and `B` of the same shape, find an orthogonal (or unitary in
    the case of complex input) matrix `R` that most closely maps `A` to `B` using the
    algorithm given in [1]_.

    Parameters
    ----------
    A : (M, N) array_like
        Matrix to be mapped.
    B : (M, N) array_like
        Target matrix.
    check_finite : bool, optional
        Whether to check that the input matrices contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------
    R : (N, N) ndarray
        The matrix solution of the orthogonal Procrustes problem.
        Minimizes the Frobenius norm of ``(A @ R) - B``, subject to

Review comment (suggestion):
```suggestion
@xp_capabilities(jax_jit=False, allow_dask_compute=2)
```

Code after:
"""
Solve the orthogonal Procrustes problem.

"""

from scipy._lib._util import _apply_over_batch
from ._decomp_svd import svd
from scipy._lib._array_api import array_namespace, xp_capabilities, _asarray, is_numpy


__all__ = ['orthogonal_procrustes']


@xp_capabilities(
    jax_jit=False,
    skip_backends=[("dask.array", "full_matrices=True is not supported by dask")],
)
@_apply_over_batch(('A', 2), ('B', 2))
def orthogonal_procrustes(A, B, check_finite=True):
    """
    Compute the matrix solution of the orthogonal (or unitary) Procrustes problem.

    Given matrices `A` and `B` of the same shape, find an orthogonal (or unitary in
    the case of complex input) matrix `R` that most closely maps `A` to `B` using the
    algorithm given in [1]_.

    Parameters
    ----------
    A : (M, N) array_like
        Matrix to be mapped.
    B : (M, N) array_like
        Target matrix.
    check_finite : bool, optional
        Whether to check that the input matrices contain only finite numbers.
        Disabling may give a performance gain, but may result in problems
        (crashes, non-termination) if the inputs do contain infinities or NaNs.

    Returns
    -------