You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently one can reshape a memoryview using .cast(...) like so...
In [1]: m = memoryview(b"abcdef")
In [2]: m2 = m.cast("B", (2, 3))
However it is not currently possible to specify the strides when reshaping the memoryview. This would be useful if the memoryview should be F-order or otherwise strided. To that end, syntax like this would be useful...
In [1]: m = memoryview(b"abcdef")
In [2]: m2 = m.cast("B", (2, 3), (1, 2))
I surely don't understand what the third argument means. What's (1, 2) there, and what stride does it produce?
jakirkham commented on Jan 13, 2022
jakirkhammannequin
MannequinAuthor
More actions
The 2nd argument is the strides. IOW it is just specifying how to traverse the buffer in memory to visit each of the dimensions.
For the first example where strides is not specified, Python makes them C-ordered. IOW m2.strides would be (3, 1). Effectively this is represented like this:
[[ b"a", b"c", b"e"],
[ b"b", b"d', b"f"]]
For the second case where strides are overridden (so m2.strides would be (1, 2)), we get something like this:
[[b"a", b"b", b"c"],
[b"d", b"e", b"f"]]
In either case the 1 here has specified which dimension is fastest to traverse along. IOW that content is adjacent in memory.
Should add the reason it is 1 is that for uint8_t (or format "B"), this is that type's size. If we had a different format, this would be the size of that format.
The motivating example here — m.cast("B", (2, 3), (1, 2)) — is exactly an F-contiguous view, which is being added as memoryview.cast(..., order='F') in gh-78959 (PR gh-153663):
>>>m.cast("B", (2, 3), order='F').strides
(1, 2)
Supporting arbitrary strides is a much bigger and riskier feature: cast currently guarantees the view exactly covers the buffer (product(shape) * itemsize == len), whereas free strides can alias or read outside the buffer — essentially numpy's as_strided, which is notoriously unsafe.
@jakirkham, do you have a concrete use case for arbitrary strides that isn't covered by order='F'?
Activity
jakirkham commentedon Jul 7, 2020
Currently one can reshape a
memoryviewusing.cast(...)like so...However it is not currently possible to specify the
strideswhen reshaping thememoryview. This would be useful if thememoryviewshould be F-order or otherwise strided. To that end, syntax like this would be useful...vedgar commentedon Sep 30, 2021
I surely don't understand what the third argument means. What's (1, 2) there, and what stride does it produce?
jakirkham commentedon Jan 13, 2022
The 2nd argument is the
strides. IOW it is just specifying how to traverse the buffer in memory to visit each of the dimensions.For the first example where
stridesis not specified, Python makes them C-ordered. IOWm2.strideswould be(3, 1). Effectively this is represented like this:For the second case where strides are overridden (so
m2.strideswould be(1, 2)), we get something like this:In either case the
1here has specified which dimension is fastest to traverse along. IOW that content is adjacent in memory.Should add the reason it is
1is that foruint8_t(or format "B"), this is that type's size. If we had a different format, this would be the size of that format.HTH
serhiy-storchaka commentedon Jul 13, 2026
The motivating example here —
m.cast("B", (2, 3), (1, 2))— is exactly an F-contiguous view, which is being added asmemoryview.cast(..., order='F')in gh-78959 (PR gh-153663):Supporting arbitrary strides is a much bigger and riskier feature:
castcurrently guarantees the view exactly covers the buffer (product(shape) * itemsize == len), whereas free strides can alias or read outside the buffer — essentiallynumpy'sas_strided, which is notoriously unsafe.@jakirkham, do you have a concrete use case for arbitrary strides that isn't covered by
order='F'?