Skip to content

Array-API interfaces #25

Closed
Closed
@jorenham

Description

@jorenham

https://data-apis.org/array-api/latest/API_specification/index.html

goal

The goal is to provide Protocols that can be used to type e.g. scipy.fft.fftfreq (through its xp kwarg) and scipy.fft.fftshift (via the passed array).

the (big) problems

  • The dtype spec only defines __eq__, which also exists in object. So it's impossible to (structurally) type a "dtype".
  • In the same way, it's impossible to (structurally) type a "device".
  • Shapes are defined as tuples of "something". So the best we can do is type the number of dimensions, and ignore the axis types.

This means that static type-checkers won't be able to see the difference between a boolean array on your CPU, and a complex-floating array on a quantum computer within the core of a neutron star in the Andromeda galaxy.

so now what?

We can still figure out the following types:

  • Array + the dimensionality (because shape: tuple[?, ...] kinda tells us the ndim, but not the actual shape)
  • Namespace, which is a protocollable module-type (often named xp), that could give us
    • xp.array: the specific Array type (but there's still no HKT after asking for it for over 6 years...), and
    • xp.(bool|((u?)int|float|complex)(8|16|32|64)) -i.e. the impossible-to-type DType types (🎩 🪄 🐰)
    • xp.__array_namespace_info__() -> Info (docs), an object with some other "magical" methods:
      • .default_device() -> DefaultDevice
      • .devices() -> list[Device]
      • .dtypes(*, device: Device?, kind: Kind?) - with Kind a literal string category, which allows us to "categorize" the e.g. floats, ints, and complexes (assuming the lib properly typed it), i.e. as type aliases.

problem solved: just type the untypeable

Note that we can also obtain the Info type via Array, since Array.__array_namespace__() -> Namespace[Info] s.t. Namespace[InfoT].__array_namespace_info__() -> InfoT (ignoring the versions).
So we can get all dtype types from either Array or Namespace, and we can either one from the other, and vice-versa (i.e. bidirectionally in both ways, and also the other way around).

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions