3 files were added to this release more than 14 days after its initial publication. Inspect the release files before installing.
Cython Memory Helper
cymem provides two small memory-management helpers for Cython. They make it easy to tie memory to a Python object’s life-cycle, so that the memory is freed when the object is garbage collected.
The most useful is cymem.Pool, which acts as a thin wrapper around the calloc function:
>>> from cymem.cymem cimport Pool >>> cdef Pool mem = Pool() >>> data1 = <int*>mem.alloc(10, sizeof(int)) >>> data2 = <float*>mem.alloc(12, sizeof(float))
The Pool object saves the memory addresses internally, and frees them when the object is garbage collected. Typically you’ll attach the Pool to some cdef’d class. This is particularly handy for deeply nested structs, which have complicated initialization functions. Just pass the pool object into the initializer, and you don’t have to worry about freeing your struct at all — all of the calls to Pool.alloc will be automatically freed when the Pool expires.
Installation
Installation is via pip, and requires Cython.
pip install cymem
Example Use Case: An array of structs
Let’s say we want a sequence of sparse matrices. We need fast access, and a Python list isn’t performing well enough. So, we want a C-array or C++ vector, which means we need the sparse matrix to be a C-level struct — it can’t be a Python class. We can write this easily enough in Cython:
"""Example without Cymem
To use an array of structs, we must carefully walk the data structure when
we deallocate it.
"""
from libc.stdlib cimport calloc, free
cdef struct SparseRow:
size_t length
size_t* indices
double* values
cdef struct SparseMatrix:
size_t length
SparseRow* rows
cdef class MatrixArray:
cdef size_t length
cdef SparseMatrix** matrices
def __cinit__(self, list py_matrices):
self.length = 0
self.matrices = NULL
def __init__(self, list py_matrices):
self.length = len(py_matrices)
self.matrices = <SparseMatrix**>calloc(len(py_matrices), sizeof(SparseMatrix*))
for i, py_matrix in enumerate(py_matrices):
self.matrices[i] = sparse_matrix_init(py_matrix)
def __dealloc__(self):
for i in range(self.length):
sparse_matrix_free(self.matrices[i])
free(self.matrices)
cdef SparseMatrix* sparse_matrix_init(list py_matrix) except NULL:
sm = <SparseMatrix*>calloc(1, sizeof(SparseMatrix))
sm.length = len(py_matrix)
sm.rows = <SparseRow*>calloc(sm.length, sizeof(SparseRow))
cdef size_t i, j
cdef dict py_row
cdef size_t idx
cdef double value
for i, py_row in enumerate(py_matrix):
sm.rows[i].length = len(py_row)
sm.rows[i].indices = <size_t*>calloc(sm.rows[i].length, sizeof(size_t))
sm.rows[i].values = <double*>calloc(sm.rows[i].length, sizeof(double))
for j, (idx, value) in enumerate(py_row.items()):
sm.rows[i].indices[j] = idx
sm.rows[i].values[j] = value
return sm
cdef void* sparse_matrix_free(SparseMatrix* sm) except *:
cdef size_t i
for i in range(sm.length):
free(sm.rows[i].indices)
free(sm.rows[i].values)
free(sm.rows)
free(sm)
We wrap the data structure in a Python ref-counted class at as low a level as we can, given our performance constraints. This allows us to allocate and free the memory in the __cinit__ and __dealloc__ Cython special methods.
However, it’s very easy to make mistakes when writing the __dealloc__ and sparse_matrix_free functions, leading to memory leaks. cymem prevents you from writing these deallocators at all. Instead, you write as follows:
"""Example with Cymem.
Memory allocation is hidden behind the Pool class, which remembers the
addresses it gives out. When the Pool object is garbage collected, all of
its addresses are freed.
We don't need to write MatrixArray.__dealloc__ or sparse_matrix_free,
eliminating a common class of bugs.
"""
from cymem.cymem cimport Pool
cdef struct SparseRow:
size_t length
size_t* indices
double* values
cdef struct SparseMatrix:
size_t length
SparseRow* rows
cdef class MatrixArray:
cdef size_t length
cdef SparseMatrix** matrices
cdef Pool mem
def __cinit__(self, list py_matrices):
self.mem = None
self.length = 0
self.matrices = NULL
def __init__(self, list py_matrices):
self.mem = Pool()
self.length = len(py_matrices)
self.matrices = <SparseMatrix**>self.mem.alloc(self.length, sizeof(SparseMatrix*))
for i, py_matrix in enumerate(py_matrices):
self.matrices[i] = sparse_matrix_init(self.mem, py_matrix)
cdef SparseMatrix* sparse_matrix_init_cymem(Pool mem, list py_matrix) except NULL:
sm = <SparseMatrix*>mem.alloc(1, sizeof(SparseMatrix))
sm.length = len(py_matrix)
sm.rows = <SparseRow*>mem.alloc(sm.length, sizeof(SparseRow))
cdef size_t i, j
cdef dict py_row
cdef size_t idx
cdef double value
for i, py_row in enumerate(py_matrix):
sm.rows[i].length = len(py_row)
sm.rows[i].indices = <size_t*>mem.alloc(sm.rows[i].length, sizeof(size_t))
sm.rows[i].values = <double*>mem.alloc(sm.rows[i].length, sizeof(double))
for j, (idx, value) in enumerate(py_row.items()):
sm.rows[i].indices[j] = idx
sm.rows[i].values[j] = value
return sm
All that the Pool class does is remember the addresses it gives out. When the MatrixArray object is garbage-collected, the Pool object will also be garbage collected, which triggers a call to Pool.__dealloc__. The Pool then frees all of its addresses. This saves you from walking back over your nested data structures to free them, eliminating a common class of errors.
Metadata
Release files for cymem 1.31.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Files added late
3 files were uploaded more than 14 days after the first file in this release.
While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.
We recommend inspecting the release files before installing.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cymem-1.31.1.tar.gz | 33.7 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| cymem-1.31.1-cp35-none-win_amd64.whl | CPython 3.5 | none | Windows x86-64 | Details |
| cymem-1.31.1-cp35-cp35m-manylinux1_x86_64.whl | CPython 3.5 | CPython 3.5 pymalloc | Linux glibc 2.5+ x86-64 | Details |
| cymem-1.31.1-cp35-cp35m-macosx_10_6_intel.whl | CPython 3.5 | CPython 3.5 pymalloc | macOS 10.6+ Intel (x86-64, i386) | Details |
| cymem-1.31.1-cp34-none-win_amd64.whl | CPython 3.4 | none | Windows x86-64 | Details |
| cymem-1.31.1-cp34-cp34m-manylinux1_x86_64.whl | CPython 3.4 | CPython 3.4 pymalloc | Linux glibc 2.5+ x86-64 | Details |
| cymem-1.31.1-cp34-cp34m-macosx_10_6_intel.whl | CPython 3.4 | CPython 3.4 pymalloc | macOS 10.6+ Intel (x86-64, i386) | Details |
| cymem-1.31.1-cp27-none-win_amd64.whl | CPython 2.7 | none | Windows x86-64 | Details |
| cymem-1.31.1-cp27-cp27mu-manylinux1_x86_64.whl | CPython 2.7 | CPython 2.7 pymalloc wide-unicode | Linux glibc 2.5+ x86-64 | Details |
| cymem-1.31.1-cp27-cp27m-macosx_10_6_intel.whl | CPython 2.7 | CPython 2.7 pymalloc | macOS 10.6+ Intel (x86-64, i386) | Details |
Total release size: 384.3 kB
Release files / cymem-1.31.1.tar.gz
| Download URL | cymem-1.31.1.tar.gz |
|---|---|
| Size | 33.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d21d652e9c7eb0711f8b328515cacab1787783d151cc9c2365b5e6a14d10bf32
|
|
BLAKE2b-256 checksum How to use checksums |
b92b569c36a66587f5f3459d1adf8fca94489b9887c36572593d32c3b0f730a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp35-none-win_amd64.whl
| Download URL | cymem-1.31.1-cp35-none-win_amd64.whl |
|---|---|
| Size | 25.4 kB |
| Tags | CPython 3.5 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
0be17b3ee12b4b75bab7d292b6952e0d72cb641db45903f37b5a28153e825541
|
|
BLAKE2b-256 checksum How to use checksums |
335af52fdf5f10bceb7482381ce7a299c684c39a62954fc295681b62fb97a91f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp35-cp35m-manylinux1_x86_64.whl
File added late
This file was uploaded more than 14 days after the first file in this release.
While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.
We recommend inspecting the release file before installing.
| Download URL | cymem-1.31.1-cp35-cp35m-manylinux1_x86_64.whl |
|---|---|
| Size | 71.1 kB |
| Tags | CPython 3.5 CPython 3.5 pymalloc Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
f43fe23bfad0f1dda38bd4c3b1ddcf915f0650c84dbc7c4f5145d36109e8e95a
|
|
BLAKE2b-256 checksum How to use checksums |
4c1ad913d81cfe6f803217a4958d111b26291f76653a0dd5ae240ba58cd924a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp35-cp35m-macosx_10_6_intel.whl
| Download URL | cymem-1.31.1-cp35-cp35m-macosx_10_6_intel.whl |
|---|---|
| Size | 22.8 kB |
| Tags | CPython 3.5 CPython 3.5 pymalloc macOS 10.6+ Intel (x86-64, i386) |
|
SHA-256 checksum How to use checksums |
588acb15567a0feb7954f10a0372c38baf77e2860d89262c60c13cbdeabd23d9
|
|
BLAKE2b-256 checksum How to use checksums |
1eea64a740322da1866368629eb0754ee8e0efb821d4f9d737b977f10f42d980
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp34-none-win_amd64.whl
| Download URL | cymem-1.31.1-cp34-none-win_amd64.whl |
|---|---|
| Size | 24.2 kB |
| Tags | CPython 3.4 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
13102a1aa5e19f2685029789ba4cca2010bd9417323eabba0b7ea17f41451fd4
|
|
BLAKE2b-256 checksum How to use checksums |
115c04696375a9ff54b8d5141e2dd5a048e8bc948791147e2e6ce9bf2ee27e69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp34-cp34m-manylinux1_x86_64.whl
File added late
This file was uploaded more than 14 days after the first file in this release.
While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.
We recommend inspecting the release file before installing.
| Download URL | cymem-1.31.1-cp34-cp34m-manylinux1_x86_64.whl |
|---|---|
| Size | 72.0 kB |
| Tags | CPython 3.4 CPython 3.4 pymalloc Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
110409a78b0b7e2f8dc858293556c4a071612c30c52d7f97681042d63f495185
|
|
BLAKE2b-256 checksum How to use checksums |
c2e2e6e590362e114489d21edbe75ec5fab387567bd33d7c005deea1f843d279
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp34-cp34m-macosx_10_6_intel.whl
| Download URL | cymem-1.31.1-cp34-cp34m-macosx_10_6_intel.whl |
|---|---|
| Size | 22.7 kB |
| Tags | CPython 3.4 CPython 3.4 pymalloc macOS 10.6+ Intel (x86-64, i386) |
|
SHA-256 checksum How to use checksums |
8dada09070ffacd6fbba0a6c3090062238e57154cc5bf10c2e1a1919268f328a
|
|
BLAKE2b-256 checksum How to use checksums |
debaac4592292d958892a412851375f31235af40ae7e2c19dede661a2625ff07
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp27-none-win_amd64.whl
| Download URL | cymem-1.31.1-cp27-none-win_amd64.whl |
|---|---|
| Size | 23.8 kB |
| Tags | CPython 2.7 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
9099fac0039bfa1806c3c9d4fb521c9bb64d59e0e539d1f9337abd72e6fabb89
|
|
BLAKE2b-256 checksum How to use checksums |
70958c33eb85f50f40406d535e58b7f3bc922dc9fb818a91b401e58a64d07681
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp27-cp27mu-manylinux1_x86_64.whl
File added late
This file was uploaded more than 14 days after the first file in this release.
While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.
We recommend inspecting the release file before installing.
| Download URL | cymem-1.31.1-cp27-cp27mu-manylinux1_x86_64.whl |
|---|---|
| Size | 66.2 kB |
| Tags | CPython 2.7 CPython 2.7 pymalloc wide-unicode Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
00121923e4a7b4f6f9abbf119684a1ad72a5be8edd5f098f2a219d2042612edf
|
|
BLAKE2b-256 checksum How to use checksums |
b233eb2f07f928120c8a4cd9df2845a62ec4cf96eb657eec59d8496304398bce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / cymem-1.31.1-cp27-cp27m-macosx_10_6_intel.whl
| Download URL | cymem-1.31.1-cp27-cp27m-macosx_10_6_intel.whl |
|---|---|
| Size | 22.3 kB |
| Tags | CPython 2.7 CPython 2.7 pymalloc macOS 10.6+ Intel (x86-64, i386) |
|
SHA-256 checksum How to use checksums |
e68bd6fee09345fc556143eb2c78941b78ed7afbd1a6abfe59c2392ffd8fcc02
|
|
BLAKE2b-256 checksum How to use checksums |
dd3e951f3dd078371dc66be01bd4abdfcdfea262e8d287b0365cbe62008699cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |