I'm looking into using ctypes for using C functions manipulating SSE (__m128) data that have to be aligned on 16 bytes boundaries.
I could not find a simple way to control the alignment of memory allocated by ctypes, so, right now, I'm making ctypes call a C function that provides a correctly aligned memory buffer.
The problem I have with this approach is that I have to manually explicitly release this memory to prevent it from being leaked.
Is there a way to control the alignment of memory allocated by ctypes ? or is there a way to register a cleanup function to release memory allocated by a C function called by ctypes (apart from standard python operator __del__) ?
What is the best path to follow ?
I've been taking some time to investigate, I came up with a function that should allow me to allocate arbitrary aligned memory with ctypes, basically relying on the fact that ctypes should keep a reference on the unaligned memory buffer, while having an instance starting at an aligned position in the buffer.
Still have to test this in production.
import ctypes
def ctypes_alloc_aligned(size, alignment):
bufSize = size+(alignment-1)
raw_memory = bytearray(bufSize)
ctypes_raw_type = (ctypes.c_char * bufSize)
ctypes_raw_memory = ctypes_raw_type.from_buffer(raw_memory)
raw_address = ctypes.addressof(ctypes_raw_memory)
offset = raw_address % alignment
offset_to_aligned = (alignment - offset) % alignment
ctypes_aligned_type = (ctypes.c_char * (bufSize-offset_to_aligned))
ctypes_aligned_memory = ctypes_aligned_type.from_buffer(raw_memory, offset_to_aligned)
return ctypes_aligned_memory
I suppose that c_ulonglong
(64 bit) must be 64-bit aligned; it's a start. Then the doc suggests that you can use _pack_
to control alignment of structures. These two are not exactly what you want, but by combining them you can allocate 8-byte aligned structs without holes.
Let's assume a struct with with 3 8-byte aligned elements .v0
, .v1
, .v2
. Use addressof()
to see if the struct is 16-byte aligned. If it is, use .v0
and .v1
for your 128-bit value; if it's not, use .v1
and .v2
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With