Taking generate as an example:
|
array_1d = np.ascontiguousarray(array.ravel(),dtype=float) |
|
#assert(array_1d.strides[0] == array_1d.itemsize) |
|
_a = array_1d.__array_interface__['data'][0] |
|
self._rng.generate(len(array_1d), _a) |
|
if array_1d.data != array.data: |
|
# array_1d is not a view into the original array. Need to copy back. |
|
np.copyto(array, array_1d.reshape(array.shape), casting='unsafe') |
The result of ascontinguousarray can share memory with the input array yet the if array_1d.data != array.data: check can fail resulting in an unnecessary copy.
The issue can be illustrated in the following code:
import numpy as np
array = np.empty((10, 20, 30), dtype=float)
array_1d = np.ascontiguousarray(array.ravel(),dtype=float)
# data is not the same
assert array.data != array_1d.data
# because array_1d is a view of array
assert array.data == array_1d.base.data # note the use of base here
# arrays share memory
assert np.shares_memory(array, array_1d)
# double check
array_1d[:] = 2
assert np.all(array == 2)
Replacing if array_1d.data != array.data: with if not np.shares_memory(array, array_1d): should fix the issue.
Taking
generateas an example:GalSim/galsim/random.py
Lines 265 to 271 in ee177aa
The result of
ascontinguousarraycan share memory with the input array yet theif array_1d.data != array.data:check can fail resulting in an unnecessary copy.The issue can be illustrated in the following code:
Replacing
if array_1d.data != array.data:withif not np.shares_memory(array, array_1d):should fix the issue.