예제 #1
0
        /// <summary>
        /// Configures the layout of CUFFT output in FFTW‐compatible modes.
        /// When FFTW compatibility is desired, it can be configured for padding
        /// only, for asymmetric complex inputs only, or to be fully compatible.
        /// </summary>
        /// <param name="plan">The plan.</param>
        /// <param name="mode">The mode.</param>
        public override void SetCompatibilityMode(FFTPlan plan, eCompatibilityMode mode)
        {
            CUFFTCompatibility cumode = (CUFFTCompatibility)mode;
            FFTPlanEx          planEx = Plans[plan];
            CUFFTResult        res    = _driver.cufftSetCompatibilityMode(planEx.CudaFFTHandle, cumode);

            if (res != CUFFTResult.Success)
            {
                throw new CudafyHostException(res.ToString());
            }
        }
예제 #2
0
        private void DoExecute <T, U>(FFTPlan plan, Array input, Array output, bool inverse = false)
        {
            //_gpu.VerifyOnGPU(input);
            //_gpu.VerifyOnGPU(output);
            EmuDevicePtrEx inputPtr   = _gpu.GetDeviceMemory(input) as EmuDevicePtrEx;
            EmuDevicePtrEx outputPtr  = _gpu.GetDeviceMemory(output) as EmuDevicePtrEx;
            FFTPlanEx      planEx     = Plans[plan];
            Ifftw_plan     fftwplan   = inverse ? planEx.FFTWInvPlan : planEx.FFTWFwdPlan;
            int            insize     = Marshal.SizeOf(typeof(T));
            int            inoffset   = inputPtr.OffsetBytes;
            int            outoffset  = outputPtr.OffsetBytes;
            int            outsize    = Marshal.SizeOf(typeof(U));
            int            batchSize  = plan.BatchSize;
            int            planLength = plan.Length;
            int            N          = planEx.N;

            unsafe
            {
                GCHandle inhandle  = new GCHandle();
                GCHandle outhandle = new GCHandle();
                try
                {
                    inhandle  = GCHandle.Alloc(inputPtr.DevPtr, GCHandleType.Pinned);
                    outhandle = GCHandle.Alloc(outputPtr.DevPtr, GCHandleType.Pinned);

                    long srcAddress = inhandle.AddrOfPinnedObject().ToInt64();
                    long dstAddress = outhandle.AddrOfPinnedObject().ToInt64();

                    int srcOffset = 0;
                    int dstOffset = 0;
                    //for (int b = 0; b < batchSize; b++)
                    {
                        IntPtr srcOffsetPtr = new IntPtr(srcAddress + inoffset + (srcOffset * insize));
                        GPGPU.CopyMemory(fftwplan.Input, srcOffsetPtr, (uint)(N * insize * batchSize));

                        fftwplan.Execute();
                        IntPtr dstIntPtrOffset = new IntPtr(dstAddress + outoffset + (dstOffset * outsize));
                        GPGPU.CopyMemory(dstIntPtrOffset, fftwplan.Output, (uint)(N * outsize * batchSize));

                        //srcOffset += planLength;
                        // dstOffset += planLength;
                    }
                }
                finally
                {
                    inhandle.Free();
                    outhandle.Free();
                }
            }
        }
예제 #3
0
        //[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
        //private static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);

        /// <summary>
        /// Frees the specified plan.
        /// </summary>
        /// <param name="plan">The plan.</param>
        public override void Remove(FFTPlan plan)
        {
            FFTPlanEx planEx = Plans[plan];

            if (planEx.DataType == eDataType.Single)
            {
                fftwf.destroy_plan(planEx.FFTWFwdPlan.Handle);
                fftwf.destroy_plan(planEx.FFTWInvPlan.Handle);
            }
            else if (planEx.DataType == eDataType.Double)
            {
                fftw.destroy_plan(planEx.FFTWFwdPlan.Handle);
                fftw.destroy_plan(planEx.FFTWInvPlan.Handle);
            }
            Plans.Remove(plan);
        }
예제 #4
0
        /// <summary>
        /// Sets the stream.
        /// </summary>
        /// <param name="plan">The plan to set the stream for.</param>
        /// <param name="streamId">The stream id.</param>
        public override void SetStream(FFTPlan plan, int streamId)
        {
            if (streamId < 0)
            {
                throw new ArgumentOutOfRangeException("streamId");
            }
            CUstream   cus    = (CUstream)_gpu.GetStream(streamId);
            FFTPlanEx  planEx = Plans[plan];
            cudaStream cs     = new cudaStream();
            //cs.Value = cus.Pointer.ToInt32();
            CUFFTResult res = _driver.cufftSetStream(planEx.CudaFFTHandle, cs);

            if (res != CUFFTResult.Success)
            {
                throw new CudafyMathException(CudafyMathException.csCUDA_EXCEPTION_X, res);
            }
        }
예제 #5
0
        /// <summary>
        /// Frees the specified plan.
        /// </summary>
        /// <param name="plan">The plan.</param>
        public override void Remove(FFTPlan plan)
        {
            FFTPlanEx planEx = Plans[plan];

            CUFFTResult res = _driver.cufftDestroy(planEx.CudaFFTHandle);

            if (res != CUFFTResult.Success)
            {
                //throw new CudafyHostException(res.ToString());
                Debug.WriteLine("remove plan failed: " + res.ToString());
            }
            else
            {
                Debug.WriteLine("remove plan succeeded: " + res.ToString());
            }
            Plans.Remove(plan);
        }
예제 #6
0
        private void DoExecute(FFTPlan plan, object input, object output, bool inverse = false)
        {
            FFTPlanEx     planEx = Plans[plan];
            CUDevicePtrEx inPtrEx;
            CUDevicePtrEx outPtrEx;

            inPtrEx  = _gpu.GetDeviceMemory(input) as CUDevicePtrEx;
            outPtrEx = _gpu.GetDeviceMemory(output) as CUDevicePtrEx;

            CUFFTDirection dir = inverse ? CUFFTDirection.Inverse : CUFFTDirection.Forward;
            CUFFTResult    res = CUFFTResult.ExecFailed;

            if (planEx.CudaFFTType == CUFFTType.C2C)
            {
                res = _driver.cufftExecC2C(planEx.CudaFFTHandle, inPtrEx.DevPtr, outPtrEx.DevPtr, dir);
            }
            else if (planEx.CudaFFTType == CUFFTType.C2R)
            {
                res = _driver.cufftExecC2R(planEx.CudaFFTHandle, inPtrEx.DevPtr, outPtrEx.DevPtr);
            }
            else if (planEx.CudaFFTType == CUFFTType.D2Z)
            {
                res = _driver.cufftExecD2Z(planEx.CudaFFTHandle, inPtrEx.DevPtr, outPtrEx.DevPtr);
            }
            else if (planEx.CudaFFTType == CUFFTType.R2C)
            {
                res = _driver.cufftExecR2C(planEx.CudaFFTHandle, inPtrEx.DevPtr, outPtrEx.DevPtr);
            }
            else if (planEx.CudaFFTType == CUFFTType.Z2D)
            {
                res = _driver.cufftExecZ2D(planEx.CudaFFTHandle, inPtrEx.DevPtr, outPtrEx.DevPtr);
            }
            else if (planEx.CudaFFTType == CUFFTType.Z2Z)
            {
                res = _driver.cufftExecZ2Z(planEx.CudaFFTHandle, inPtrEx.DevPtr, outPtrEx.DevPtr, dir);
            }
            if (res != CUFFTResult.Success)
            {
                throw new CudafyMathException(res.ToString());
            }
        }