Get integer size at compile time in Cython

Is it possible, and if so, how to determine the bit size of integer data types in Cython?

I am trying to do something like this to get integer sizes:

cdef WORD_BITS = 0
IF sizeof(unsigned long long) == 8:
    WORD_BITS = 64
    DEF VECTOR_LENGTH_SHIFT_AMOUNT = 6
ELSE:
    WORD_BITS = 32
    DEF VECTOR_LENGTH_SHIFT_AMOUNT = 5

ctypedef unsigned long long word_t

cdef int vector_length(size_t bit_size):

    cdef size_t size = bit_size >> VECTOR_LENGTH_SHIFT_AMOUNT
    if size << VECTOR_LENGTH_SHIFT_AMOUNT < bit_size:
        size += 1
    return size

cdef class BitVector(object):

    cdef size_t length
    cdef size_t array_size
    cdef word_t *array

    def __cinit__(self, size_t size):
        self.length = size
        self.array_size = vector_length(size)
        self.array = <word_t *>calloc(self.array_size, sizeof(word_t))

    def __dealloc__(self):
        free(self.array)

I need to process both individual bits of the elements of the array and the elements themselves, and therefore I need to know how many bits they contain (to calculate the correct masks / shifts). Trying to compile code like the above gives:

$python setup.py build_ext --inplace
Compiling bitvector.pyx because it changed.
Cythonizing bitvector.pyx

Error compiling Cython file:
------------------------------------------------------------
...
cimport cython


# check whether we are running on a 64 or 32 bit architecture.
cdef WORD_BITS = 0
IF sizeof(unsigned long long) == 8:
  ^
------------------------------------------------------------

bitvector.pyx:7:3: Invalid compile-time expression

Traceback (most recent call last):
  File "setup.py", line 6, in <module>
    ext_modules=cythonize('bitvector.pyx')
  File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 673, in cythonize
    cythonize_one(*args[1:])
  File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 737, in cythonize_one
    raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: bitvector.pyx

Is there a working alternative?

I know there is a header stdint.hthat should define integer types, but I can't figure out how to use it, since:

  • I do not know how to check if a type is defined (for example, how do you write IF uint64_t is not defined:in cython?).
  • Cython , , DEF, IF s, , stdint.h.

, Cython, , , C , cython C.

: cython , C?

, - :

cdef WORD_BITS = 0
IF sizeof(unsigned long long) == 8:
    WORD_BITS = 64
    DEF VECTOR_LENGTH_SHIFT_AMOUNT = 6
ELSE:
    WORD_BITS = 32
    DEF VECTOR_LENGTH_SHIFT_AMOUNT = 5

ctypedef unsigned long long word_t

, IF " " Cython, C ?

+5
1

vector_length, sizeof. Cython sizeof, . . glibc sizeof CHAR_BIT : https://www.gnu.org/software/libc/manual/html_node/Width-of-Type.html.

from libc.stdlib cimport calloc, free
from libc.limits cimport CHAR_BIT

ctypedef unsigned long long word_t

cdef size_t vector_length(size_t bit_size):
    cdef size_t bits_per_word = CHAR_BIT*sizeof(word_t)
    return (bit_size + bits_per_word - 1) / bits_per_word

cdef class BitVector(object):
    cdef size_t length
    cdef size_t array_size
    cdef word_t *array

    def __cinit__(self, size_t size):
        self.length = size
        self.array_size = vector_length(size)
        self.array = <word_t *>calloc(self.array_size, sizeof(word_t))

    def __dealloc__(self):
        free(self.array)

, unsigned long long 64 (https://en.wikipedia.org/wiki/C_data_types). , , 64 32-, - 64- .

0
source

All Articles