nifty.cl.any_array module#

class AnyArray(obj=None, *args, **kwargs)[source]#

Bases: NDArrayOperatorsMixin

Wrapper for numpy and cupy arrays for flexible computations on CPU and GPUs

AnyArray supports both CPU (numpy.ndarray) and GPU (cupy.ndarray) arrays. It provides automatic device-aware operations and conversions. It implements numpy-like operations such as element-wise operations, vector dot products, and norms. Additionally it can also be directly plugged into numpy functions (like np.fft.fftn or np.transpose) - the work will be dispatched correctly to numpy and cupy.

ALLOWED_WRAPPEES are numpy.ndarray and, if cupy is install installed and GPUs are available, also cupy.ndarray.

Parameters:

arr (ALLOWED_WRAPPEES or AnyArray) – The input array that will be wrapped into an AnyArray instance. It can be either a numpy.ndarray (for CPU-based computations) or a cupy.ndarray (for GPU-based computations, if cupy is available). If arr is already an AnyArray, it is returned as is without modification. Scalars are automatically converted into numpy.ndarray instances. The stored array retains its original memory location, and no implicit device transfers are performed during initialization.

property H#
property T#
__init__(arr)[source]#
all(*args, **kwargs)#
any(*args, **kwargs)#
asnumpy()[source]#

Returns a NumPy representation of the AnyArray.

This method ensures that the array is located on the CPU (numpy.ndarray). If the AnyArray is already on the CPU, it is returned as-is. Otherwise, it is transferred from GPU to CPU.

If the AnyArray is read-only, the returned NumPy array will also be flagged as read-only.

Returns:

The content of the AnyArray as NumPy array.

Return type:

numpy.ndarray

astype(*args, **kwargs)[source]#
at(device_id, *, check_fail=True)[source]#

Returns a copy of the AnyArray on the specified device.

This method ensures that the AnyArray instance is located on the requested device (CPU or GPU). If the array is already on the target device, it is returned as-is. Otherwise, a copy is made and transferred to the target device.

If the source array is read-only, the copied array on the new device will also be locked as read-only.

Parameters:
  • device_id (int) – The target device ID: - -1 for CPU (numpy.ndarray) - >= 0 for a specific GPU (cupy.ndarray)

  • check_fail (bool, optional) – If True, additional debugging checks are performed to catch unexpected device transfers (default: True).

Returns:

A new AnyArray instance located on the specified device.

Return type:

AnyArray

Raises:

RuntimeError – If _config[“fail_on_device_copy”] is enabled and an unexpected device transfer occurs.

Examples

>>> arr = AnyArray(np.array([1, 2, 3]))
>>> arr.device_id
-1  # Currently on CPU
>>> gpu_arr = arr.at(0)  # Move to GPU (if available)
>>> gpu_arr.device_id
0  # Now on GPU
>>> cpu_arr = gpu_arr.at(-1)  # Move back to CPU
>>> cpu_arr.device_id
-1  # Now on CPU again
conj(*args, **kwargs)#
conjugate(*args, **kwargs)#
copy()[source]#

Returns a deep copy of the AnyArray.

This method creates an independent copy of the array, ensuring that modifications to the copy do not affect the original.

The copy is always writeable, even if the original AnyArray is read-only.

Returns:

A new AnyArray instance containing a copy of the original data.

Return type:

AnyArray

Examples

>>> arr = AnyArray(np.array([1, 2, 3]))
>>> arr_copy = arr.copy()
>>> (arr_copy.val is arr.val)
False  # The data is copied, not shared
property device_id#

Returns the device ID where the array is stored.

  • -1 represents a CPU (NumPy) array.

  • A non-negative integer represents a GPU (CuPy) array on the corresponding GPU device.

Returns:

The device ID of the array.

Return type:

int

property dtype#
flatten(*args, **kwargs)#
static full(shape, val, device_id=-1)[source]#

Create an AnyArray filled with a specified scalar value.

This method generates an AnyArray of the given shape, filled with the specified scalar value. The resulting array can be placed on a specific device (CPU or GPU) by specifying device_id.

Parameters:
  • shape (tuple of int) – The shape of the output array.

  • val (scalar (int, float, complex)) – The value to fill the array with. Must be a real or complex scalar.

  • device_id (int, optional (default: -1)) – The target device for the array: - -1 for CPU (numpy.ndarray). - >=0 for GPU (cupy.ndarray with the specified device ID).

Returns:

An AnyArray instance of the specified shape, filled with val, located on the specified device.

Return type:

AnyArray

Examples

Create a 3x3 array filled with 5 on the CPU:

>>> AnyArray.full((3, 3), 5)

Create a 2x2 complex array filled with 2 + 3j on GPU (device 0):

>>> AnyArray.full((2, 2), 2 + 3j, device_id=0)
property imag#
lock()[source]#

Make the AnyArray instance read-only.

This method sets the underlying array to be non-writable, preventing any modifications to its contents. For numpy.ndarray, it updates the writeable flag to False.

Once locked, the array cannot be modified unless a writable copy is created.

Note

For cupy.ndarray, write protection is not yet implemented due to limitations in cupy (see cupy/cupy#2616). However, we still try to track the read-only status via an internal attribute (AnyArray._writeable).

Examples

>>> arr = AnyArray(np.array([1, 2, 3]))
>>> arr.lock()
>>> arr[0] = 10  # Raises ValueError
max(*args, **kwargs)#
mean(*args, **kwargs)#
min(*args, **kwargs)#
property nbytes#
property ndim#
norm(ord=2)[source]#
prod(*args, **kwargs)#
ptw(op, *args, **kwargs)[source]#

Performs an element-wise operation on the array.

This method applies a specified pointwise operation to the array, using the corresponding function from nifty.cl.pointwise.

Parameters:
  • op (str) – The name of the pointwise operation (e.g., exp).

  • *args (tuple) – Additional positional arguments for the operation.

  • **kwargs (dict) – Additional keyword arguments for the operation.

Returns:

A new AnyArray instance with the result of the operation.

Return type:

AnyArray

ptw_with_deriv(op, *args, **kwargs)[source]#

Performs element-wise operation and derivative simultaneously.

This method applies a specified pointwise operation to the array and also computes its derivative, using the corresponding function from nifty.cl.pointwise.

Parameters:
  • op (str) – The name of the pointwise operation (e.g., exp).

  • *args (tuple) – Additional positional arguments for the operation.

  • **kwargs (dict) – Additional keyword arguments for the operation.

Returns:

A tuple containing: - The result of the operation (AnyArray). - The derivative of the operation (AnyArray).

Return type:

tuple of AnyArray

Examples

>>> arr = AnyArray(np.array([4, 9, 16]))
>>> res, deriv = arr.ptw_with_deriv("sqrt")
>>> res.val
array([2., 3., 4.])
>>> deriv.val
array([0.25, 0.16666667, 0.125])
property readonly#

Indicates whether the AnyArray instance is read-only.

Note

For cupy.ndarray, write protection is not fully supported yet.

Returns:

True if the array is read-only, False otherwise.

Return type:

bool

Examples

>>> arr = AnyArray(np.array([1, 2, 3]))
>>> arr.readonly
False
>>> arr.lock()
>>> arr.readonly
True
property real#
reshape(*args, **kwargs)#
property shape#
property size#
std(*args, **kwargs)#
property strides#
sum(*args, **kwargs)#
property val#

Returns the underlying array.

This property provides access to the raw numpy.ndarray or cupy.ndarray wrapped by AnyArray.

Returns:

The wrapped array.

Return type:

numpy.ndarray or cupy.ndarray

var(*args, **kwargs)#
vdot(x)[source]#
view(*args, **kwargs)[source]#

Returns a new view of the array with the specified shape or type.

This method creates a view of the underlying data without making a copy. It behaves similarly to numpy.ndarray.view(), returning an AnyArray instance wrapping the new view.

Views share memory with the original array; modifying one modifies the other.

Parameters:

documentation. (See numpy or cupy)

Returns:

A new AnyArray instance representing the view.

Return type:

AnyArray

Examples

>>> arr = AnyArray(np.array([[1, 2], [3, 4]]))
>>> view = arr.view()
>>> view is arr
False  # Different object, but shares memory
assert_no_device_copies()[source]#
func(op)[source]#