Skip to content

ENH: Using Array API standard for functions implemented using pure Python and NumPy API #15354

@IvanYashchuk

Description

@IvanYashchuk

Is your feature request related to a problem? Please describe.

SciPy's roadmap includes a section about GPU and distributed array support. It would be great to start moving in this direction and the recent NumPy 1.22 release together with CuPy and Array API standard can help with that. The Array API documentation describes the use case for SciPy here.

Latest NumPy and CuPy releases include Array API compatible modules (numpy.array_api and cupy.array_api). Some other libraries like PyTorch aim to get their main module to be Array API compatible soon.

Describe the solution you'd like.

Array objects from the Array API compatibles libraries have a method to retrieve its module: __array_namespace__(). This module needs to be used as a numpy/np replacement. Since the array instances carry the module information SciPy codebase doesn't need to introduce any additional dependencies.

Current way of using NumPy

import numpy as np

def current_scipy_func(input):
    # use `np` to do computation on `input`
    input_array = np.asarray(input)
    ...

should be changed to (note there's no import numpy as np)

def new_scipy_func(input):
    xp = get_namespace(input)
    # now use `xp` instead of `np`
    input_array = xp.asarray(input)
    ...

See NEP 47 for a possible implementation of the get_namespace function: https://numpy.org/neps/nep-0047-array-api-standard.html#appendix-a-possible-get-namespace-implementation.
In order to preserve the current behavior when passing regular NumPy arrays, the get_namespace function in SciPy should return the result of the __array_namespace__() method of the input array if the method exists or numpy otherwise.

The first candidates for the Array API adoption are:

  • Signal module
    All functions except max_sen_len, sosfilt, lombscargle, upfirdn and Peak finding algorithms that use Cython.
  • Special module
    All non-ufunc functions.
    non_ufuncs = [f for f in scipy.special.__all__ if not isinstance(getattr(scipy.special, f), numpy.ufunc)]

Describe alternatives you've considered.

No response

Additional context (e.g. screenshots, GIFs)

Purpose and scope of the Array API standard: https://data-apis.org/array-api/latest/purpose_and_scope.html
Blog post about the demo of using Array API with SciPy signal module: https://labs.quansight.org/blog/2021/10/array-libraries-interoperability/
NEP 47 — Adopting the array API standard https://numpy.org/neps/nep-0047-array-api-standard.html
Previous discussion on a related topic: #10204

Metadata

Metadata

Assignees

No one assigned

    Labels

    array typesItems related to array API support and input array validation (see gh-18286)duplicateIssues that describe the same problem or that are reported multiple timesenhancementA new feature or improvement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions