odlgroup / odl

Operator Discretization Library https://odlgroup.github.io/odl/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MKL error in fft test

adler-j opened this issue · comments

I'm getting the following on my Mac

impl = 'numpy', odl_floating_dtype = dtype('complex256')

    def test_fourier_trafo_call(impl, odl_floating_dtype):
        # Test if all variants can be called without error
        dtype = odl_floating_dtype
    
        # Not supported, skip
        if dtype == np.dtype('float16') and impl == 'pyfftw':
            return
    
        shape = 10
        halfcomplex, _ = _params_from_dtype(dtype)
        space_discr = odl.uniform_discr(0, 1, shape, dtype=dtype)
    
        ft = FourierTransform(space_discr, impl=impl, halfcomplex=halfcomplex)
        ift = ft.inverse
    
        one = space_discr.one()
>       assert np.allclose(ift(ft(one)), one)

odl/test/trafos/fourier_test.py:473: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
odl/operator/operator.py:686: in __call__
    out = self._call_out_of_place(x, **kwargs)
odl/operator/operator.py:50: in _default_call_out_of_place
    result = op._call_in_place(x, out, **kwargs)
odl/trafos/fourier.py:898: in _call
    out[:] = self._call_numpy(x.asarray())
odl/trafos/fourier.py:1315: in _call_numpy
    out = np.fft.fftn(preproc, axes=self.axes)
/anaconda3/lib/python3.7/site-packages/mkl_fft/_numpy_fft.py:676: in fftn
    output = mkl_fft.fftn(a, s, axes)
mkl_fft/_pydfti.pyx:760: in mkl_fft._pydfti.fftn
    ???
mkl_fft/_pydfti.pyx:746: in mkl_fft._pydfti._fftnd_impl
    ???
mkl_fft/_pydfti.pyx:627: in mkl_fft._pydfti._iter_fftnd
    ???
mkl_fft/_pydfti.pyx:121: in mkl_fft._pydfti.fft
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???
E   ValueError: First argument must be a complex or real sequence of single or double precision

mkl_fft/_pydfti.pyx:290: ValueError

Could be an upstream bug. Have you checked if the basic call works? Like np.fft.fft(array, axes=<something>). Could be that MKL FFT does not support the axes argument.

I think it is because MKL does not support long doubles, I'll see how we can fix this. Do we have some machinery for detecting if MKL is used over e.g. native numpy?

Maybe np.__config__.show() gives you something?

Since there's no Numpy package in the traceback, this probably means that the mkl_fft package is dropped in as replacement for numpy.fft. But no idea where that happens.

If you import from numpy.fft.fftpack instead of from numpy.fft you will get non-MKL versions. That is what we ended up doing in the pyFFTW test suite. However, be aware that fftpack itself has now been replaced by pocketfft (numpy/numpy#11888) in NumPy master, so any fix should probably take that into consideration as well.

That makes sense, thanks @grlee77 for the pointer.

For our issue, I think we should just xfail the test case once we find a way to detect the presence of mkl_fft. This could work:

>>> # Default Numpy FFT
>>> np.fft.fft.__module__
'numpy.fft.fftpack'
>>> # MKL FFT
>>> np.fft.fft.__module__
'mkl_fft._numpy_fft'

Yeah, skipping if np.fft.fft.__module__.startswith('mkl') sounds reasonable.

@adler-j In view of #1461 I think the best way of doing this would be to wrap all the dtype parameters with pytest.param and add an xfail decorator with the above condition to 'float128' and/or 'complex256'.