New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't read a F-contiguous memoryview in physical order #80026
Comments
This request is motivated in detail here: In short: in C, when you have a Py_buffer, you can directly read the memory in whatever order you want (including physical order). It is not possible in pure Python, though. Somewhat unintuitively, memoryview.tobytes() as well as bytes(memoryview) read bytes in *logical* order, even though it flattens the dimensions and doesn't keep the original type. Logical order is different from physical order for Fortran-contiguous arrays. One possible way of alleviating this would be to offer a memoryview.transpose() method, similar to the Numpy transpose() method (see https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.transpose.html). One could also imagine a memoryview.to_c_contiguous() method. Or even: a memoryview.raw_memory() method, that would 1) flatten dimensions 2) cast to 'B' format 3) keep physical order. |
Yes, it's modeled after NumPy's tobytes(): >>> x = np.array(list(range(6)), dtype="int8").reshape(2,3)
>>> x.tobytes()
b'\x00\x01\x02\x03\x04\x05'
>>> x.T.tobytes()
b'\x00\x03\x01\x04\x02\x05'
>>>
>>>
>>> memoryview(x).tobytes()
b'\x00\x01\x02\x03\x04\x05'
>>> memoryview(x.T).tobytes()
b'\x00\x03\x01\x04\x02\x05' I guess the reason is that without a type it's easier to serialize the logical array by default, so you can always assume C when you read back. NumPy also has an 'F' parameter though that flips the order: >>> x.tobytes('F')
b'\x00\x03\x01\x04\x02\x05' It would be possible to add this to memoryview as well. |
raw_bytes() is also possible of course. I assume it would do nothing and just dump the memory. Or tobytes('F') AND tobytes('raw'). |
Well, raw_memory() would avoid a copy, which is useful. As for tobytes(), if we want to follow NumPy, we can have 'F' mean if F-contiguous, 'C' otherwise: >>> a = np.arange(12, dtype='int8').reshape((3,4))
>>> a.tobytes('A')
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b'
>>> a.tobytes('A') == a.T.tobytes('A')
True |
Sorry, my fingers slipped. Let me try again: As for tobytes(), if we want to follow NumPy, we can have 'A' mean 'F' if F-contiguous, 'C' otherwise: [...] |
Yes, following NumPy looks like the sanest option for tobytes(), so I memory.raw() is of course complicated by the fact that things like So we'd need to restrict to contiguous views anyway, which makes |
Yes, it would probably be a simpler way of writing |
Sorry if I'm just misunderstanding the discussion here. Would it make sense to have an |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: