Source code for vbi.models.cupy.utils
import numpy as np
try:
import cupy as cp
except:
cp = None
[docs]
def get_module(engine="gpu"):
"""
Switches the computational engine between GPU and CPU.
Parameters
----------
engine : str, optional
The computational engine to use. Can be either "gpu" or "cpu".
Default is "gpu".
Returns
-------
module
The appropriate array module based on the specified engine.
If "gpu", returns the CuPy module. If "cpu", returns the NumPy module.
Raises
------
ValueError
- If the specified engine is not "gpu" or "cpu".
- If CuPy is not installed.
"""
if engine == "gpu":
if cp is None:
raise ValueError("CuPy is not installed.")
else:
return cp.get_array_module(cp.array([1]))
else:
return np
# return cp.get_array_module(np.array([1]))
[docs]
def tohost(x):
'''
move data to cpu if it is on gpu
Parameters
----------
x: array
data
Returns
-------
array
data moved to cpu
'''
if cp is not None and isinstance(x, cp.ndarray):
return cp.asnumpy(x)
return x
[docs]
def todevice(x):
'''
move data to gpu
Parameters
----------
x: array
data
Returns
-------
array
data moved to gpu
'''
return cp.asarray(x)
[docs]
def move_data(x, engine):
if engine == "cpu":
return tohost(x)
elif engine == "gpu":
return todevice(x)
[docs]
def repmat_vec(vec, ns, engine):
'''
repeat vector ns times
Parameters
----------
vec: array 1d
vector to be repeated
ns: int
number of repetitions
engine: str
cpu or gpu
Returns
-------
vec: array [len(vec), n_sim]
repeated vector
'''
vec = np.tile(vec, (ns, 1)).T
vec = move_data(vec, engine)
return vec
[docs]
def is_seq(x):
'''
check if x is a sequence
Parameters
----------
x: any
variable to be checked
Returns
-------
bool
True if x is a sequence
'''
return hasattr(x, '__iter__')
[docs]
def prepare_vec(x, ns, engine, dtype="float"):
'''
check and prepare vector dimension and type
Parameters
----------
x: array 1d
vector to be prepared, if x is a scalar, only the type is changed
ns: int
number of simulations
engine: str
cpu or gpu
Returns
-------
x: array [len(x), n_sim]
prepared vector
'''
xp = get_module(engine)
if not is_seq(x):
return eval(f"{dtype}({x})")
else:
x = np.array(x)
if x.ndim == 1:
x = repmat_vec(x, ns, engine)
elif x.ndim == 2:
assert(x.shape[1] == ns), "second dimension of x must be equal to ns"
x = move_data(x, engine)
else:
raise ValueError("x.ndim must be 1 or 2")
return x.astype(dtype)
[docs]
def get_(x, engine="cpu", dtype="f"):
"""
Parameters
----------
x : array-like
The input array to be converted.
engine : str, optional
The computation engine to use. If "gpu", the array is transferred from GPU to CPU. Defaults to "cpu".
dtype : str, optional
The desired data type for the output array. Defaults to "f".
Returns
-------
array-like
The converted array with the specified data type.
"""
if engine == "gpu":
return x.get().astype(dtype)
else:
return x.astype(dtype)