jztools.shared_memory#
The following operations produce xndarray objects:
Copying an
xndarray– the copy will have new shared memory.Slicing an
xndarray– the slice will reference the original shared memory.
The following operations do not:
Operators that are not in-place, e.g.,
new_arr = 1 + x_arr.
Classes
|
SharedMemoryManager that can be used as an argument when creating multiprocessing processes. |
|
Class derived from |
Exceptions
|
- exception jztools.shared_memory.InvalidAsXndarray(obj)#
Bases:
Exception
- class jztools.shared_memory.XSharedMemoryManager(*args, **kwargs)#
Bases:
SharedMemoryManagerSharedMemoryManager that can be used as an argument when creating multiprocessing processes.
Allocated shared memory can be viewed using
ls /dev/shm -lth- from_ndarray(arr, **kwargs)#
Cretes an xndarray from the input np.ndarray.
- empty(*args, **kwargs)#
Creates an empty array in shared memory.
- class jztools.shared_memory.xndarray(sh_mem: str | SharedMemory | None, manager: XSharedMemoryManager, shape, dtype, offset, strides, scope: str | None = 'local', **kwargs)#
Bases:
ndarrayClass derived from
numpy.ndarraythat uses shared memory. Implements a pickling interface that pickles a reference to the shared memory instead of the actual buffer contents and is compatible with multiprocessing. This inclues support for array slicing - sliced arrays will be sent as shared memory arrays. When indexing produces a new copy of memory (e.g., when using non-uniform indexing such asarr[list([0,10])]),__getitem__()returns a numpy.ndarray- Parameters:
sh_mem – The shared memory with the contents of this array.
scope – Specifies when the shared memory will be released. Valid values are
'local','remote', orNone. See Memory management.
Memory management
Shared memory needs to be released in order to avoid memory leaks that can persist after the end of the program.
The approached used herein relies on
XSharedMemoryManager– a context manager derived frommultiprocessing’sSharedMemoryManagerthat further supports being pickled and initializingxndarrayinstances. All shared memory created within a givenXSharedMemoryManagercontext will be released upon exiting the context.Within the context,
xndarrayswill be released based on theirscopeattribute, which can take one of the following values:'local'The shared memory will be released when the
xndarraygoes out of scope in the process where it was declared.When pickling, this will be converted to
Noneso that child processes do not release the memory.
Warning
An array created in child process should not use
scope='local', as the created array will be garbage-collected in the child process. Attempting to access it in the parent process can result in undefined behavior, including raising aFileNotFoundErrorexception, or accessing the memory before it is garbage-collected.'remote'When the
xndarrayis pickled, this value will be pickled as'local'.The shared memory will hence be released when the unpickled array goes out of scope in the process that unpickled it, unless that process changes the value of the
xndarray.scopeattribute.
NoneThe shared memory will not be automatically released – it is the user’s responsibility to release the shared memory using method
release(). Otherwise, the shared memory will be released by the memory manager, but will result in a memory leak in the meantime.
Examples
from jztools.shared_memory import XSharedMemoryManager, xndarray from concurrent.futures import ProcessPoolExecutor import numpy as np with XSharedMemoryManager() as smm: # Fill an xndarry with random data N = int(1e6) rng = np.random.default_rng(0) xarr = smm.empty(N) rng.random(N, out=xarr) # Take the mean of both halves in different processes futures = [] with ProcessPoolExecutor() as pool: futures.append(pool.submit(np.mean, xarr[:N//2])) futures.append(pool.submit(np.mean, xarr[N//2:])) results = [x.result().item() for x in futures] print(results)
[0.5001123274748334, 0.5002061854525354]
- scope: str | None = None#
Can be one of
'local','remote'orNone. See Memory management.
- property shared_memory_manager#
Inherited from the source xndarray.
- is_shared()#
Returns
Trueif the xndarray points to data in shared memory. IfFalse, the xndarray is no different than a regularnumpy.ndarray
- property shared_memory#
Inherited from the source xndarray.
- release()#
Unlinks the underlying shared memory block. The array should not be accessed after it is released. In most situations, calling this method should not be necessary, as the
scopebased mechanism deals with releasing the underlying shared memory.For example, if the array was initialized with the
scope='local'keyword arg (the default), this method is called as part of the array’s__del__.
- classmethod from_ndarray(manager: XSharedMemoryManager, arr: ndarray, **kwargs) → xndarray#
Creates a new array in newly-allocated shared memory and copies the data in arr to it.
Keyword arguments are passed
empty().
- as_ndarray() → ndarray#
Returns a copy of the array in non-shared memory.