Cythonの整数データ型のサイズをビット単位で決定することは可能ですか?
整数のサイズを取得するために、次のようなことをしようとしています:
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)
配列の要素の単一ビットと要素自体の両方を処理する必要があるため、適切なマスク/シフトを計算するために、それらに含まれるビット数を知る必要があります。上記のようなコードをコンパイルしようとすると、次のようになります。
$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
有効な代替手段はありますか?
整数型を定義する必要があるヘッダーがあることは知っていstdint.h
ますが、それを使用する方法が思い浮かびません:
- 型が定義されていないかどうかを確認する方法がわかりません (たとえば、cython ではどのように記述します
IF uint64_t is not defined:
か?)。 DEF
Cython のドキュメントには、およびコンパイラによって定義されたもののみがIF
s でチェックできると記載されているため、とにかく使用できるとは思えませstdint.h
ん。
これは、Cython から C ではなく、C からマシン コードにコンパイルする場合にのみ実行できるチェックであるため、Cython では実行できないようです。
この種のチェックが C ソース コードに追加されるような方法で cython 拡張機能を作成することは可能でしょうか?
つまり、どういうわけか書くことができます:
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ファイルに同等のコードがありますか?