Trying to implement PyFFTW in nopython mode

Hello Everyone! I have been working on a code that uses PyFFTW. Currently, I have a class that requires an array for its initialization, which is used in constructing fftn and ifftn routines using its shape which is called via the corresponding class method. Now, I need the instances of this class as a part of another class that has to be ‘jitclassed’ (hence the need to run it in nopython mode).
As per the documentation on Extension APIs, I can make numba support the class using it. Am I correct? And Is it possible for this class?
I have tried writing the code relevant to it with the help of the provided example case (‘Interval’ Class), but I am not clear about what are the appropriate types for function pointers and the corresponding elements in the c.pyapi object. So, I need some pointers to help in figuring the right configuration for numba to support this class.

hi @lightpeak008 , to work with classes you can work with jitclasses, or you can work with extension APIs (either the low-level one or the high-level structref). Jitclasses are easier and unless you really need to go to the extension API, it’s better to start with jitclasses.

The interval class example is the low level extension and by far the hardest to work with. If you need to avoid jitclasses is better to try with structref

You can see an example of using function “pointers” as members of jitclasses here How do I make a jitclass with a jitted function member? and here Typed list of jitted functions in jitclass

hope this helps,
Luk

Thank you very much for your reply. I tried with jitclasses for the class defined below

import numpy as np
import pyfftw

pyfftw.config.PLANNER_EFFORT = 'FFTW_MEASURE'


class PyfftwMod:
    def __init__(self, arr_in: np.ndarray):
        # DEFAULT PARAMETERS: overwrite_input = False, auto_align_input = True
        #                     auto_contiguous = True, avoid_copy = False
        self.arr_in = pyfftw.empty_aligned(arr_in.shape, dtype='complex128')
        self.fftn = pyfftw.builders.fftn(self.arr_in, auto_align_input=True,
                                         planner_effort=pyfftw.config.PLANNER_EFFORT)
        self.ifftn = pyfftw.builders.ifftn(self.arr_in, auto_align_input=True,
                                           planner_effort=pyfftw.config.PLANNER_EFFORT)

    def do_fft(self, arr_in):
        self.arr_in[:] = arr_in
        return np.copy(self.fftn())

    def do_ifft(self, arr_in):
        self.arr_in[:] = arr_in
        return np.copy(self.ifftn())

But since pyfftw is not recognized by numba, it keep giving me errors when I specify the class attributes that are function pointers as ‘nb.types.voidptr’. Should I use a different type for these attributes? Or will jitclasses not work for this case?

Since pyfftw is not recognized by numba, nothing that uses the python code in pyfftw can be jitted, not jitclasses, not jit functions, not extension classes, or structref.
I checked quickly the pyfftw repo, and it seems to be a wrapper written in cython. you might be able to interface with the cython functions using High-level extension API — Numba 0.53.1-py3.7-linux-x86_64.egg documentation. If it uses cython classes then you’re out of luck.

I’ll look into implementing it via cython interfaces. But, I did try an alternative a while ago using CFFI, which I was able to put into a jitted function, thanks to the workaround using intrinsics given by stuartarchibald in CFFI void* in nopython mode, determine Numba type of `_cffi_backend.CData` · Issue #4115 · numba/numba · GitHub. I think I’ll work with that and implement the jitclass with the now jitted function member, like in your previous reply. I’ll post my implementation if I get it working.