Skip to content

RFC: add a unified inspection API namespace #640

Closed
@kgryte

Description

@kgryte

This RFC is intended to supersede #635, #636, #637, and #638, based on initial consortium feedback, and proposes to consolidate inspection APIs into a single non-public namespace.

Proposal

info = xp.__array_namespace_info__()

Returns a namespace with Array API namespace inspection utilities.

Note: the x.__array_namespace__() API supports a version kwarg. We don't follow suit here, as we assume backward compatibility, whereby a consumer may ask for a particular version of the array API standard and a conforming library may return a newer version. That version should still be compliant with the older specified version (backward compat guarantee), and thus, the inspection API return values should still be applicable. Stated more succinctly: conforming array libraries are expected to be "evergreen" and only have a single Array API implementation, not separate implementations for each revision of the standard.

Methods

info.capabilities() -> dict[str,bool]

info.capabilities() -> dict[str,bool]

Returns a dictionary of static "capabilities", such as whether a conforming library supports boolean indexing or data-dependent output shapes.

Key values should be either False (does not support) or True (does support). For example,

{
    'boolean_indexing': False | True,
    'data_dependent_shapes': False | True
}

info.default_device() -> device

info.default_device()

Returns an object for the default device.

info.default_dtypes( /, *, device: device) -> dict[str, dtype]

info.default_dtypes() -> dict[str, dtype]
info.default_dtypes(device: device) -> dict[str, dtype]

Returns a dictionary having the following keys:

  • real floating: default real floating-point dtype.
  • complex floating: default complex floating-point dtype.
  • integral: default integral dtype.
  • indexing: default index dtype.
>>> info.default_dtypes()
{
    'real floating': <dtype>,
    'complex floating': <dtype>,
    'integral': <dtype>,
    'indexing': <dtype>
}
>>> info.default_dtypes(device=<device>)
{
    'real floating': <dtype>,
    'complex floating': <dtype>,
    'integral': <dtype>,
    'indexing': <dtype>
}

More keys could be added in the future, depending on evolution of the standard.

If not provided a device argument, the function would return a dictionary based on the current device (context). If provided a device argument, the function would return a dictionary as described above, but specific to the specified device.

info.dtypes( /, *, device: device, kind: Union[str, Tuple[str, ...]]) -> dict[str,dtype]

info.dtypes() -> dict[str,dtype]
info.dtypes(device: device) -> dict[str,dtype]
info.dtypes(kind: Union[dtype, str, Tuple[Union[dtype, str], ...]]) -> dict[str,dtype]
info.dtypes(kind: Union[dtype, str, Tuple[Union[dtype, str], ...]], device: device) -> dict[str,dtype]

Returns a dictionary of supported Array API data types (in canonical form; e.g., float64, float32, int32, etc).

>>> info.dtypes()
{"float64": xp.float64, "float32": xp.float32, "int32": xp.int32, ...}

Similar to the isdtype API, the function would support a "kind" kwarg for returning a dictionary of supported Array API data types belonging to the specified kind. The following kinds should be supported, matching the isdtype API:

  • 'bool': boolean data types (e.g., bool).
  • 'signed integer': signed integer data types (e.g., int8, int16, int32, int64).
  • 'unsigned integer': unsigned integer data types (e.g., uint8, uint16, uint32, uint64).
  • 'integral': integer data types. Shorthand for ('signed integer', 'unsigned integer').
  • 'real floating': real-valued floating-point data types (e.g., float32, float64).
  • 'complex floating': complex floating-point data types (e.g., complex64, complex128).
  • 'numeric': numeric data types. Shorthand for ('integral', 'real floating', 'complex floating').
>>> info.dtypes(kind="real floating")
{"float64": xp.float64, "float32": xp.float32}

If not provided a device argument, the function should return a dictionary of supported data types for the current device (context). If provided a device argument, the function should return a dictionary of supported data types for the specified device.

>>> info.dtypes(device=<device>)
{"float32": xp.float32, "int32": xp.int32, "int8": xp.int8, "uint8": xp.uint8, ...}
>>> info.dtypes(kind="real floating", device=<device>)
{"float32": xp.float32}

Note: a hasattr check is not sufficient as a means of determining dtype support, as dtype support can vary depending on the device. A conforming array library may be fully compliant for its default device, but unable to be fully compliant on other supported devices. In which case, simply checking whether a dtype object exists in the main namespace is insufficient to determine whether a downstream consumer can actually use a specific dtype object for a particular device/execution context.

info.devices()

info.devices() -> List[device]

Returns a list of supported devices.

Related Links

Metadata

Metadata

Assignees

No one assigned

    Labels

    API extensionAdds new functions or objects to the API.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions