/// <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()); } }
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(); } } }
//[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); }
/// <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); } }
/// <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); }
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()); } }