Расширение NumPy с помощью Cython - PullRequest
4 голосов
/ 22 декабря 2009

Я пытаюсь обернуть файл заголовка, который имеет множество функций, подобных этой

test.h

void test(int N, int* data_in, int* data_out);

чтобы я мог использовать их от numpy.

Сейчас у меня есть следующий код Cython:

test.pyx

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    void _test 'test' (int, int*, int*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

Однако, когда я пытаюсь скомпилировать его, я получаю сообщение об ошибке:

Error converting Pyrex file to C:
(...)
Cannot assign type 'test.itype_t *' to 'int *'

Как я могу это исправить?

Ответы [ 2 ]

4 голосов
/ 28 декабря 2009

Эта проблема в настоящее время обсуждается в списке рассылки Cython; по-видимому, это связано с небольшой ошибкой в ​​одной из библиотек Cython:

http://codespeak.net/mailman/listinfo/cython-dev

На данный момент, один из возможных обходных путей - использовать массивы NumPy типа dtype np.long, а затем вместо этого написать «ctypedef np.long_t itype_t». Тогда вам просто нужно порадовать код на C длинными целыми вместо целых.

2 голосов
/ 19 февраля 2011

Другой обходной путь, который не требует от вас изменения значений с int с на long с: измените сигнатуру функции в блоке cdef extern from '...'. Cython использует объявления в блоке cdef extern только для проверки типов при генерации файла .c, но сгенерированный код C просто делает #include "VolumeForm.h", так что вы можете сойти с рук.

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    # NOTE: We changed the int* declarations to itype_t*
    void _test 'test' (int, itype_t*, itype_t*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

Cython не жалуется на вышесказанное.

...