Ejemplo n.º 1
0
 static void WorkaroundKnownIssue(CudaAccelerator accelerator, CuFFTAPI api)
 {
     // The CUDA release notes for 11.2 to 11.3 (inclusive) contains a known issue:
     // - cuFFT planning and plan estimation functions may not restore correct
     //   context affecting CUDA driver API applications.
     //
     // This workaround restores the accelerator context so that deallocation of
     // the memory buffers can be performed on the correct context.
     //
     // Based on the versions of CuFFT released, apply workaround to CuFFT v10.4.x.
     //
     // Release 11.1.1   CuFFT v10.3.0.105
     // Release 11.2     CuFFT v10.4.0.72
     // Release 11.3     CuFFT v10.4.2.58
     // Release 11.4     CuFFT v10.5.0.43
     //
     CuFFTException.ThrowIfFailed(
         api.GetProperty(LibraryPropertyType.MAJOR_VERSION, out var major));
     CuFFTException.ThrowIfFailed(
         api.GetProperty(LibraryPropertyType.MINOR_VERSION, out var minor));
     if (major == 10 && minor == 4)
     {
         CudaException.ThrowIfFailed(
             CudaAPI.CurrentAPI.SetCurrentContext(accelerator.NativePtr));
     }
 }
Ejemplo n.º 2
0
        // Use the low-level CuFFT API to perform an inverse transform.
        static void DoInversePlan(
            CudaAccelerator accelerator,
            CuFFTAPI api,
            Complex[] input,
            out Complex[] output)
        {
            using var stream       = accelerator.CreateStream() as CudaStream;
            using var inputBuffer  = accelerator.Allocate1D(input);
            using var outputBuffer = accelerator.Allocate1D <Complex>(input.Length);

            CuFFTException.ThrowIfFailed(
                api.Plan1D(
                    out var plan,
                    input.Length,
                    CuFFTType.CUFFT_Z2Z,
                    batch: 1));
            try
            {
                CuFFTException.ThrowIfFailed(
                    api.SetStream(plan, stream));
                CuFFTException.ThrowIfFailed(
                    api.ExecZ2Z(
                        plan,
                        inputBuffer.View.BaseView,
                        outputBuffer.View.BaseView,
                        CuFFTDirection.INVERSE));

                output = outputBuffer.GetAsArray1D(stream);
            }
            finally
            {
                CuFFTException.ThrowIfFailed(
                    api.Destroy(plan));
            }
            WorkaroundKnownIssue(accelerator, api);

            // Scale the output to obtain the inverse.
            for (var i = 0; i < output.Length; i++)
            {
                output[i] /= output.Length;
            }

            Console.WriteLine("Inverse Values:");
            for (var i = 0; i < output.Length; i++)
            {
                Console.WriteLine($"  [{i}] = {output[i].Real}");
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Constructs a new instance to wrap a cuFFT plan.
 /// </summary>
 public CuFFTPlan(CuFFTAPI api, IntPtr plan)
 {
     API        = api;
     PlanHandle = plan;
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Constructs a new CuFFT instance.
 /// </summary>
 public CuFFT(CuFFTAPIVersion?version)
 {
     API = CuFFTAPI.Create(version);
 }