Czy jest możliwe, a jeśli tak, jak określić rozmiar bitów typów danych całkowitych w Cython?Uzyskaj wielkość liczby całkowitej w czasie kompilacji w Cython
Próbuję zrobić coś takiego, aby uzyskać całkowite rozmiary:
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)
muszę obsługiwać zarówno pojedyncze kawałki elementów tablicy i samych elementów, a więc mam wiedzieć, ile zawiera ich bitów (aby obliczyć właściwe maski/przesunięcia). Próba skompilowania kodu takiego jak powyższe:
$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
Czy istnieje działająca alternatywa?
Wiem, że istnieje stdint.h
nagłówek, który powinien określać typy całkowite, ale nie mogę wymyślić sposób, żeby go wykorzystać od:
- nie wiem, jak sprawdzić, czy typ jest nie zdefiniowano (np. jak piszesz
IF uint64_t is not defined:
w cytoncie?). - Dokumentacja Cythona stwierdza, że tylko rzeczy zdefiniowane przez
DEF
i kompilator mogą być sprawdzone wIF
s, więc wątpię, czy byłbym w stanie użyć w każdym raziestdint.h
.
Wydaje się, że jest to niewykonalne w Cython ponieważ kontrola Chcę, aby można przeprowadzić tylko przy kompilacji z C do kodu maszynowego, a nie z Cython do C.
Teraz zastanawiam się: czy możliwe jest napisanie rozszerzenia cythonu w taki sposób, że ten rodzaj sprawdzenia jest dodawany w kodzie źródłowym C?
To znaczy, mogę jakoś napisać:
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
W taki sposób, aby ten IF
„nie są przetwarzane” przez Cython, ale jest on przekazywany przez aw końcowym pliku C jest równoważny kod?
Miałem dokładnie ten sam problem. Czy miałeś szczęście? – PierreBdR
@PierreBdR Niestety nie. Postanowiłem zawsze używać 32-bitowego typu danych, mimo że jest on nieoptymalny w 64-bitowych komputerach. Jeśli chcesz otrzymać odpowiedź, możesz rozważyć dodanie nagrody do tego pytania (możesz ją edytować, jeśli uważasz, że można ją poprawić). – Bakuriu