Allocation and Array Interfaces

GT4Py does not provide its own data container class, but supports established python standards for exposing N-dimensional buffers. There is a minimalistic interface allowing to specify the correspondence of buffer dimensions to the semantic dimensions assumed in the stencil. This correspondence does not necessarily need to be specified since the stencils specify a default ordering.

GT4Py provides utilities to allocate buffers that have optimal layout and alignment for a given backend.

In this document, we describe the interfaces for

  • supported buffer interfaces

  • exposing dimension labels and the behavior for default values

  • performance-optimal allocation

Interfaces

Stencil Calls

Supported Buffer Interfaces

The user is free to choose a buffer interface (or multiple) as long as it is supported by numpy.asarray in case a CPU backend is chosen or cupy.asarray for a GPU backend respectively. If multiple buffer interfaces are implemented the provided information needs to agree otherwise the behaviour is undefined. Similarly the backend is also free to choose what buffer interface to use in order to retrieve the required information (e.g. pointer, strides, etc.) In particular, we support the following interfaces to expose a buffer:

Internally, gt4py uses the utilities gt4py.utils.as_numpy and gt4py.utils.as_cupy to retrieve the buffers. GT4Py developers are advised to always use those utilities as to guarantee support across gt4py as the supported interfaces are extended.

Dimension Mapping

The user can optionally implement a __gt_dims__ attribute in the object implementing any of the supported buffer interfaces. The returned object should be a tuple of strings labeling the dimensions in index order. As a fallback if the attribute is not implemented, it is assumed that the buffer contains the dimensions given in the annotations (by means of gtscript.Field) exactly in the same order.

Valid dimension strings are "I", "J", "K" as well as decimal string representations of integer numbers to denote data dimensions.

Developers are advised to use the utility gt4py.utils.get_dims(storage, annotation), which implements this lookup.

Note: Support for xarray can be added manually by the user by means of the mechanism described here.

Default Origin

A buffer object can optionally implement the __gt_origin__ attribute which is used as the origin value unless overwritten by the origin keyword argument to the stencil call.

Allocation

For the performance-optimal allocation and initialization of arrays to be used in GT4Py, we provide the following set of functions which closely resemble their NumPy counterparts (meaning of the common parameters is explained below).

The return type is either a numpy.ndarray or a cupy.ndarray, for CPU and GPU backends, respectively.

empty(shape: Sequence[int], dtype: dtype_like = np.float64, **kwargs) -> ndarray

Allocate an array with uninitialized (undefined) values.

Parameters:
  • shape: Sequence[int] Sequence of length ndim (ndim = number of dimensions) with the shape of the storage.

  • dtype: dtype_like The dtype of the storage (NumPy dtype or accepted by np.dtype()). It defaults to np.float64.

Keyword Arguments:
  • aligned_index: Sequence[int] The index of the grid point to which the memory is aligned. Note that this only partly takes the role of the deprecated default_origin parameter, since it does not imply anything about the origin or domain when passed to a stencil. (See __gt_origin__ interface instead.)

For common keyword-only arguments, please see below.

zeros(shape: Sequence[int], dtype: dtype_like = np.float64, **kwargs) -> ndarray

Allocate an array with values initialized to 0.

Parameters:
  • shape: Sequence[int] Sequence of length ndim (ndim = number of dimensions) with the shape of the storage.

  • dtype: dtype_like The dtype of the storage (NumPy dtype or accepted by np.dtype()). It defaults to np.float64.

Keyword Arguments:
  • aligned_index: Sequence[int] The index of the grid point to which the memory is aligned. Note that this only partly takes the role of the deprecated default_origin parameter, since it does not imply anything about the origin or domain when passed to a stencil. (See __gt_origin__ interface instead.)

For common keyword-only arguments, please see below.

ones(shape: Sequence[int], dtype: dtype_like = np.float64, **kwargs) -> ndarray

Allocate an array with values initialized to 1.

Parameters:
  • shape: Sequence[int] Sequence of length ndim (ndim = number of dimensions) with the shape of the storage.

  • dtype: dtype_like The dtype of the storage (NumPy dtype or accepted by np.dtype()). It defaults to np.float64.

Keyword Arguments:
  • aligned_index: Sequence[int] The index of the grid point to which the memory is aligned. Note that this only partly takes the role of the deprecated default_origin parameter, since it does not imply anything about the origin or domain when passed to a stencil. (See __gt_origin__ interface instead.)

For common keyword-only arguments, please see below.

full(shape: Sequence[int], fill_value: Number, dtype: dtype_like = np.float64, **kwargs) -> ndarray

Allocate an array with values initialized to the scalar given in fill_value.

Parameters:
  • shape: Sequence[int] Sequence of length ndim (ndim = number of dimensions) with the shape of the storage.

  • fill_value: Number. The number to which the storage is initialized.

  • dtype: dtype_like The dtype of the storage (NumPy dtype or accepted by np.dtype()). It defaults to np.float64.

Keyword Arguments:
  • aligned_index: Sequence[int] The index of the grid point to which the memory is aligned. Note that this only partly takes the role of the deprecated default_origin parameter, since it does not imply anything about the origin or domain when passed to a stencil. (See __gt_origin__ interface instead.)

For common keyword-only arguments, please see below.

from_array(data: array_like, *, dtype: dtype_like = np.float64, **kwargs) -> ndarray

Used to allocate an array with values initialized from the content of a given array.

Parameters:
  • data: array_like. The original array from which the storage is initialized.

  • dtype: dtype_like The dtype of the storage (NumPy dtype or accepted by np.dtype()). It defaults to the dtype of data.

Keyword Arguments:
  • aligned_index: Sequence[int] The index of the grid point to which the memory is aligned. Note that this only partly takes the role of the deprecated default_origin parameter, since it does not imply anything about the origin or domain when passed to a stencil. (See __gt_origin__ interface instead.)

Optional Keyword-Only Parameters

Additionally, these optional keyword-only parameters are accepted:

dimensions: Optional[Sequence[str]]

Sequence indicating the semantic meaning of the dimensions of this storage. This is used to determine the default layout for the storage. Currently supported will be "I", "J", "K" and additional dimensions as string representations of integers, starting at "0". (This information is not retained in the resulting array, and needs to be specified instead with the __gt_dims__ interface. )