Приведение указателя fftw_complex (он же double[2]) к комплексному представлению памяти cython

(Кросс-пост от пользователей cython)

Я пытаюсь использовать FFTW для некоторого кода Cython. Я сталкиваюсь с проблемами при попытке указать указатель на fftw_complex (typedef to double[2]) на сложное представление памяти, а именно (минимальный пример)

cdef extern from "fftw3.h":
    ctypedef double fftw_complex[2]
    fftw_complex* fftw_alloc_complex(int N)

cdef foo(complex[::1] input):
    complex_ny = fftw_alloc_complex(input.size)
    (<complex[:self.ny]>complex_ny)[:] = input
    # actual call to FFTW follows

терпит неудачу при приведении: «hmm.pyx:8:34: базовый тип указателя не соответствует базовому типу cython.array» (возможно, нельзя ожидать, что Cython будет знать, что double[2] может быть преобразован в комплекс, но. .. Что еще я могу сделать?)

PS: Если у кого-то есть опыт использования обертки pyFFTW напрямую из Cython, мне тоже интересно.

Заранее спасибо.


person antony    schedule 12.05.2015    source источник


Ответы (1)


Он жалуется, что тип complex_ny не совпадает с типом complex (и он не знает преобразования). Если вы сначала приведете complex_ny к complex*, а затем назначите указатель на представление памяти, оно будет более счастливым:

complex_ny = fftw_alloc_complex(input.size)
cdef complex[::1] view_of_complex_ny = <complex[:input.size]>(<complex*>complex_ny)
view_of_complex_ny[:] = input

Я уверен, вы знаете, что это работает только потому, что вы сделали так, что complex и fftw_complex имеют одинаковый размер.


Дополнение

Учитывая, что fftw_complex и complex имеют одинаковую структуру памяти, самое простое решение — просто сообщить Cython, что функции fftw_ работают с complex*, а не с fftw_complex*. На самом деле он не просматривает файлы C, чтобы убедиться, что это правда - он просто использует его для преобразования типов и выделения памяти (оба из которых должны быть в порядке)

cdef extern from "fftw3.h":
    complex* fftw_alloc_complex(int N)

def foo(complex[::1] input):
    cdef complex[::1] complex_ny
    complex_ny = <complex[:input.size]>fftw_alloc_complex(input.size)
    complex_ny[:] = input

(Вы получаете предупреждение о несовместимых типах указателей на этапе компиляции C, но это всего лишь предупреждение, и вы знаете, что типы на самом деле совместимы.)

person DavidW    schedule 13.05.2015