2013-04-02 32 views
5

Mümkün mü, ve eğer evet, Cython'daki tamsayı veri türlerinin boyutunu, bit cinsinden belirlemek mümkün mü?Cython'da derleme zamanında bir tamsayı elde edin

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) 

Ben dizinin elemanları ve elemanların kendilerinin tek bit hem işlemek gerekir ve böylece ben var: Ben tamsayılar elde etmek, böyle bir şey yapmaya çalışıyorum

boyutları kaç bit içerdiğini bilmek (uygun maskeleri/vardiyaları hesaplamak için). Yukarıdaki gibi kod derlemeye çalışıyorum:

$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 

Bir çalışma alternatifi var mı?

Ben tamsayı tiplerini tanımlamak gerekir bir stdint.h başlık olduğunu biliyorum, ama bu yana kullanmak için bir yol düşünemiyorum: bir tür olup olmadığını kontrol etmek için nasıl bilmiyorum

  • tanımlanmamış (örn. IF uint64_t is not defined: cython'a nasıl yazıyorsunuz?).
  • Cython'un belgeleri, yalnızca DEF ve derleyicinin tanımladığı şeylerin IF s adresinde kontrol edilebileceğini, dolayısıyla zaten stdint.h'u kullanabileceğinden şüphe duyduğumu belirtir. Ben yapmak istiyorum onay sadece makine koduna C derlerken gerçekleştirilen değil, Cython Şimdi

    C

    için olabilir çünkü bu gibi görünüyor

Cython uygulanabilir değildir ben şahane: Ct koduna bu tür bir kontrol eklenecek şekilde bir stelon uzantısı yazmak mümkün mü? eşdeğer olduğu bu IF Cython tarafından "işlenmez" öyle bir şekilde

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 

ama içinden ve son C dosyasında geçirilir: Demek

, ben bir şekilde yazabilir kod?

+0

Ben de aynı problemi yaşadım. Hiç şansın var mıydı? – PierreBdR

+0

@PierreBdR Ne yazık ki yok. 64 bit makinelerde yetersiz olmasına rağmen, her zaman 32 bit veri türü kullanarak yerleştim. Eğer bir cevabı istiyorsanız, bu soruya bir ödül ekleyeceğinizi düşünebilirsiniz (geliştirilebileceğini düşünüyorsanız, bunu düzenlemek için çekinmeyin). – Bakuriu

cevap

0

Boyutu ve kaydırma değerlerini tanımlamak için önişlemciyi kullanmak yerine, vector_length işlevinizi biraz değiştirerek sizeof doğrudan kullanabilirsiniz. Cython, sizeof operatörünü doğru bir şekilde çevirecek ve derleyici, türünün gerçek boyutunu derleme zamanı ile değiştirecektir. Doğru vektör boyutunu elde etmek için sizeof ve CHAR_BIT kullanımı hakkında daha fazla bilgi için glibc belgelerinden bu bölüme bakın: 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 en az 64-bit (https://en.wikipedia.org/wiki/C_data_types) olduğu Ayrıca belirtmek gerekir. Kodunuz ya da 64 ya da 32-bit olabilir, ancak standart uyumlu bir derleyici olabilir, ancak her zaman sadece 64-bit veya daha fazla olabilir gibi görünüyor.

İlgili konular