Search code examples
c#asp.net-core-webapiasp.net-core-2.1fftw.net-core-2.1

FFTW.NET DFT.FFT(pinIn, pinOut) is throwing System.InvalidOperationException in WEB API


I want to use FFTW.NET in .NET Core 2.1 WEB API. When I execute below piece of code in action, I get System.InvalidOperationException: 'IsAvailable returns false.' at DFT.FFT(pinIn, pinOut);

        Complex[] input = new Complex[1024];
        Complex[] output = new Complex[input.Length];

        //Initialize input         

        using (var pinIn = new PinnedArray<Complex>(input))
        using (var pinOut = new PinnedArray<Complex>(output))
        {
            DFT.FFT(pinIn, pinOut);
        }

Below is the stacktrace.

   at FFTW.NET.FftwPlan`2..ctor(IPinnedArray`1 buffer1, IPinnedArray`1 buffer2, Int32 rank, Int32[] n, Boolean verifyRankAndSize, DftDirection direction, PlannerFlags plannerFlags, Int32 nThreads)
   at FFTW.NET.FftwPlanC2C.Create(IPinnedArray`1 input, IPinnedArray`1 output, DftDirection direction, PlannerFlags plannerFlags, Int32 nThreads)
   at FFTW.NET.DFT.Transform(IPinnedArray`1 input, IPinnedArray`1 output, DftDirection direction, PlannerFlags plannerFlags, Int32 nThreads)
   at FFTW.NET.DFT.FFT(IPinnedArray`1 input, IPinnedArray`1 output, PlannerFlags plannerFlags, Int32 nThreads)
   at FFTW_WEB_API.Controllers.ValuesController.Get() in D:\FFTW_Test\FFTW_WEB_API\Controllers\ValuesController.cs:line 1059
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()

But the same piece of code works fine in .NET Core 2.1 Console Application.

Please suggest if I am doing something wrong.


Solution

  • IsAvailable is called internally to test whether the interop layer is happy - found here.

    It looks like it'll return false if trying to load the Dll resulted in a DllNotFoundException (via the GetVersionAndInitialize and _version).

    So the native DLLs aren't in the right place to be loaded. If it's not clear which locations are being probed for the DLLs you might want to use Process Monitor to look for the failed probing attempts to load the DLLs.