/// <summary> /// Executes a CUFTT transorm as defined by the cufftType. /// This method does an in‐place transform.<para/> /// This method is only valid for transform types where transorm direction is implicitly /// given by the type (i.e. not C2C and not Z2Z) /// </summary> /// <param name="iodata"></param> public void Exec(CUdeviceptr iodata) { switch (_type) { case cufftType.R2C: res = CudaFFTNativeMethods.cufftExecR2C(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecR2C", res)); break; case cufftType.C2R: res = CudaFFTNativeMethods.cufftExecC2R(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecC2R", res)); break; case cufftType.D2Z: res = CudaFFTNativeMethods.cufftExecD2Z(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecD2Z", res)); break; case cufftType.Z2D: res = CudaFFTNativeMethods.cufftExecZ2D(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecZ2D", res)); break; default: throw new ArgumentException("For transformation not of type R2C, C2R, D2Z or Z2D, you must specify a transform direction."); } if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
static void cufft_ERROR_CHECK(cufftResult result) { if (result != cufftResult.CUFFT_SUCCESS) { Console.Error.WriteLine(Enum.GetName(typeof(cufftResult), result)); Environment.Exit(6); // abort; } }
/// <summary> /// SetWorkArea() overrides the work area pointer associated with a plan. /// If the work area was auto-allocated, CUFFT frees the auto-allocated space. The /// cufftExecute*() calls assume that the work area pointer is valid and that it points to /// a contiguous region in device memory that does not overlap with any other work area. If /// this is not the case, results are indeterminate. /// </summary> /// <param name="workArea"></param> public void SetWorkArea(CUdeviceptr workArea) { res = CudaFFTNativeMethods.cufftSetWorkArea(_handle, workArea); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetWorkArea", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <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="mode">The <see cref="Compatibility"/> option to be used</param> public void SetCompatibilityMode(Compatibility mode) { res = CudaFFTNativeMethods.cufftSetCompatibilityMode(_handle, mode); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetCompatibilityMode", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// Associates a CUDA stream with a CUFFT plan. All kernel launches /// made during plan execution are now done through the associated /// stream, enabling overlap with activity in other streams (for example, /// data copying). The association remains until the plan is destroyed or /// the stream is changed with another call to SetStream(). /// </summary> /// <param name="stream">A valid CUDA stream created with cudaStreamCreate() (or 0 for the default stream)</param> public void SetStream(CUstream stream) { res = CudaFFTNativeMethods.cufftSetStream(_handle, stream); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetStream", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// Creates a new 2D FFT plan (old API) /// </summary> /// <param name="nx">The transform size in the X dimension (number of rows)</param> /// <param name="ny">The transform size in the Y dimension (number of columns)</param> /// <param name="type">The transform data type (e.g., C2R for complex to real)</param> public CudaFFTPlan2D(int nx, int ny, cufftType type) { _handle = new cufftHandle(); _nx = nx; _ny = ny; _type = type; res = CudaFFTNativeMethods.cufftPlan2d(ref _handle, nx, ny, type); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftPlan2d", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
// /// <summary> ///// Creates a new 3D FFT plan (old API) // /// </summary> // /// <param name="nx">The transform size in the X dimension</param> // /// <param name="ny">The transform size in the Y dimension</param> // /// <param name="nz">The transform size in the Z dimension</param> // /// <param name="type">The transform data type (e.g., R2C for real to complex)</param> // /// <param name="mode">The <see cref="Compatibility"/> option to be used</param> // public CudaFFTPlan3D(int nx, int ny, int nz, cufftType type, Compatibility mode) // : this(nx, ny, nz, type) // { // SetCompatibilityMode(mode); // } // /// <summary> ///// Creates a new 3D FFT plan (old API) // /// </summary> // /// <param name="nx">The transform size in the X dimension</param> // /// <param name="ny">The transform size in the Y dimension</param> // /// <param name="nz">The transform size in the Z dimension</param> // /// <param name="type">The transform data type (e.g., R2C for real to complex)</param> // /// <param name="stream">A valid CUDA stream created with cudaStreamCreate() (or 0 for the default stream)</param> // /// <param name="mode">The <see cref="Compatibility"/> option to be used</param> // public CudaFFTPlan3D(int nx, int ny, int nz, cufftType type, CUstream stream, Compatibility mode) // : this(nx, ny, nz, type) // { // SetStream(stream); // SetCompatibilityMode(mode); // } /// <summary> /// Creates a new 3D FFT plan (new API) /// </summary> /// <param name="handle">cufftHandle object</param> /// <param name="nx">The transform size in the X dimension</param> /// <param name="ny">The transform size in the Y dimension</param> /// <param name="nz">The transform size in the Z dimension</param> /// <param name="type">The transform data type (e.g., C2R for complex to real)</param> /// <param name="size"></param> public CudaFFTPlan3D(cufftHandle handle, int nx, int ny, int nz, cufftType type, ref SizeT size) { _handle = handle; _nx = nx; _type = type; res = CudaFFTNativeMethods.cufftMakePlan2d(_handle, nx, ny, type, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftMakePlan2d", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// During plan execution, CUFFT requires a work area for temporary storage of /// intermediate results. This call returns an estimate for the size of the work area required, /// given the specified parameters, and assuming default plan settings. Note that changing /// some plan settings, such as compatibility mode, may alter the size required for the work /// area. /// </summary> /// <param name="nx">The transform size in the x dimension</param> /// <param name="ny">The transform size in the y dimension</param> /// <param name="nz">The transform size in the z dimension</param> /// <param name="type">The transform data type (e.g., CUFFT_C2C for single /// precision complex to complex)</param> /// <returns></returns> public static SizeT EstimateSize(int nx, int ny, int nz, cufftType type) { SizeT size = new SizeT(); cufftResult res = CudaFFTNativeMethods.cufftEstimate3d(nx, ny, nz, type, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftEstimate3d", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } return(size); }
/// <summary> /// Once plan generation has been done, either with the original API or the extensible API, /// this call returns the actual size of the work area required to support the plan. Callers /// who choose to manage work area allocation within their application must use this call /// after plan generation, and after any cufftSet*() calls subsequent to plan generation, if /// those calls might alter the required work space size. /// </summary> /// <returns></returns> public SizeT GetActualSize() { SizeT size = new SizeT(); res = CudaFFTNativeMethods.cufftGetSize(_handle, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftGetSize", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } return(size); }
/// <summary> /// Creates a new 1D FFT plan (old API) /// </summary> /// <param name="nx">The transform size (e.g., 256 for a 256-point FFT)</param> /// <param name="type">The transform data type (e.g., C2C for complex to complex)</param> /// <param name="batch">Number of transforms of size nx</param> public CudaFFTPlan1D(int nx, cufftType type, int batch) { _handle = new cufftHandle(); _nx = nx; _type = type; _batch = batch; res = CudaFFTNativeMethods.cufftPlan1d(ref _handle, nx, type, batch); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftPlan1d", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// Creates only an opaque handle, and allocates small data structures on the host. The /// cufftMakePlan*() calls actually do the plan generation. It is recommended that /// cufftSet*() calls, such as cufftSetCompatibilityMode(), that may require a plan /// to be broken down and re-generated, should be made after cufftCreate() and before /// one of the cufftMakePlan*() calls. /// </summary> /// <returns></returns> public static cufftHandle Create() { cufftHandle handle = new cufftHandle(); cufftResult res = CudaFFTNativeMethods.cufftCreate(ref handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftCreate", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } return(handle); }
/// <summary> /// For IDisposable /// </summary> /// <param name="fDisposing"></param> protected virtual void Dispose(bool fDisposing) { if (fDisposing && !disposed) { //Ignore if failing res = CudaFFTNativeMethods.cufftDestroy(_handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftDestroy", res)); disposed = true; } if (!fDisposing && !disposed) { Debug.WriteLine(String.Format("ManagedCUDA not-disposed warning: {0}", this.GetType())); } }
/// <summary> /// Creates a new 3D FFT plan (old API) /// </summary> /// <param name="nx">The transform size in the X dimension</param> /// <param name="ny">The transform size in the Y dimension</param> /// <param name="nz">The transform size in the Z dimension</param> /// <param name="type">The transform data type (e.g., R2C for real to complex)</param> public CudaFFTPlan3D(int nx, int ny, int nz, cufftType type) { _handle = new cufftHandle(); _nx = nx; _ny = ny; _nz = nz; _type = type; res = CudaFFTNativeMethods.cufftPlan3d(ref _handle, nx, ny, nz, type); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftPlan3d", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// SetAutoAllocation() indicates that the caller intends to allocate and manage /// work areas for plans that have been generated. CUFFT default behavior is to allocate /// the work area at plan generation time. If cufftSetAutoAllocation() has been called /// with autoAllocate set to "false" prior to one of the cufftMakePlan*() calls, CUFFT /// does not allocate the work area. This is the preferred sequence for callers wishing to /// manage work area allocation. /// </summary> /// <param name="autoAllocate"></param> public void SetAutoAllocation(bool autoAllocate) { int auto = 0; if (autoAllocate) { auto = 1; } res = CudaFFTNativeMethods.cufftSetAutoAllocation(_handle, auto); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetAutoAllocation", res)); if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// Executes a CUFTT transorm as defined by the cufftType. /// This method does an in‐place transform. /// </summary> /// <param name="iodata"></param> /// <param name="direction">Only unsed for transformations where direction is not implicitly given by type</param> public void Exec(CUdeviceptr iodata, TransformDirection direction) { switch (_type) { case cufftType.R2C: res = CudaFFTNativeMethods.cufftExecR2C(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecR2C", res)); break; case cufftType.C2R: res = CudaFFTNativeMethods.cufftExecC2R(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecC2R", res)); break; case cufftType.C2C: res = CudaFFTNativeMethods.cufftExecC2C(_handle, iodata, iodata, direction); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecC2C", res)); break; case cufftType.D2Z: res = CudaFFTNativeMethods.cufftExecD2Z(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecD2Z", res)); break; case cufftType.Z2D: res = CudaFFTNativeMethods.cufftExecZ2D(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecZ2D", res)); break; case cufftType.Z2Z: res = CudaFFTNativeMethods.cufftExecZ2Z(_handle, iodata, iodata, direction); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecZ2Z", res)); break; default: break; } if (res != cufftResult.Success) { throw new CudaFFTException(res); } }
/// <summary> /// Creates a FFT plan configuration of dimension rank, with sizes /// specified in the array <c>n</c>. The <c>batch</c> input parameter tells CUFFT how /// many transforms to configure in parallel. With this function, batched /// plans of any dimension may be created. (old API) /// </summary> /// <param name="rank">Dimensionality of the transform (1, 2, or 3)</param> /// <param name="n">An array of size rank, describing the size of each dimension</param> /// <param name="batch">Batch size for this transform</param> /// <param name="type">Transform data type (e.g., C2C, as per other CUFFT calls)</param> public CudaFFTPlanMany(int rank, int[] n, int batch, cufftType type) { _handle = new cufftHandle(); _rank = rank; _n = n; _batch = batch; _type = type; //optional: _inembed = null; _istride = 1; _idist = 0; _onembed = null; _ostride = 1; _odist = 0; res = CudaFFTNativeMethods.cufftPlanMany(ref _handle, rank, n, _inembed, _istride, _idist, _onembed, _ostride, _odist, type, batch); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "CudaFFTPlanMany", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// SetAutoAllocation() indicates that the caller intends to allocate and manage /// work areas for plans that have been generated. CUFFT default behavior is to allocate /// the work area at plan generation time. If cufftSetAutoAllocation() has been called /// with autoAllocate set to "false" prior to one of the cufftMakePlan*() calls, CUFFT /// does not allocate the work area. This is the preferred sequence for callers wishing to /// manage work area allocation. /// </summary> /// <param name="autoAllocate"></param> public void SetAutoAllocation(bool autoAllocate) { int auto = 0; if (autoAllocate) auto = 1; res = CudaFFTNativeMethods.cufftSetAutoAllocation(_handle, auto); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetAutoAllocation", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// SetWorkArea() overrides the work area pointer associated with a plan. /// If the work area was auto-allocated, CUFFT frees the auto-allocated space. The /// cufftExecute*() calls assume that the work area pointer is valid and that it points to /// a contiguous region in device memory that does not overlap with any other work area. If /// this is not the case, results are indeterminate. /// </summary> /// <param name="workArea"></param> public void SetWorkArea(CUdeviceptr workArea) { res = CudaFFTNativeMethods.cufftSetWorkArea(_handle, workArea); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetWorkArea", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// Once plan generation has been done, either with the original API or the extensible API, /// this call returns the actual size of the work area required to support the plan. Callers /// who choose to manage work area allocation within their application must use this call /// after plan generation, and after any cufftSet*() calls subsequent to plan generation, if /// those calls might alter the required work space size. /// </summary> /// <returns></returns> public SizeT GetActualSize() { SizeT size = new SizeT(); res = CudaFFTNativeMethods.cufftGetSize(_handle, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftGetSize", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); return size; }
/// <summary> /// For IDisposable /// </summary> /// <param name="fDisposing"></param> protected virtual void Dispose(bool fDisposing) { if (fDisposing && !disposed) { //Ignore if failing res = CudaFFTNativeMethods.cufftDestroy(_handle); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftDestroy", res)); disposed = true; } if (!fDisposing && !disposed) Debug.WriteLine(String.Format("ManagedCUDA not-disposed warning: {0}", this.GetType())); }
/// <summary> /// Creates a new 2D FFT plan (new API) /// </summary> /// <param name="handle">cufftHandle object</param> /// <param name="nx">The transform size in the X dimension (number of rows)</param> /// <param name="ny">The transform size in the Y dimension (number of columns)</param> /// <param name="type">The transform data type (e.g., C2R for complex to real)</param> public CudaFFTPlan2D(cufftHandle handle, int nx, int ny, cufftType type) { SizeT size = new SizeT(); _handle = handle; _nx = nx; _type = type; res = CudaFFTNativeMethods.cufftMakePlan2d(_handle, nx, ny, type, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftMakePlan2d", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// /// </summary> /// <param name="error"></param> /// <param name="message"></param> /// <param name="exception"></param> public CudaFFTException(cufftResult error, string message, Exception exception) : base(message, exception) { this._cudaFFTError = error; }
/// <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="mode"></param> public void SetCompatibilityMode(Compatibility mode) { res = CudaFFTNativeMethods.cufftSetCompatibilityMode(_handle, mode); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetCompatibilityMode", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// Executes a CUFTT transorm as defined by the cufftType. /// This method does an in‐place transform.<para/> /// This method is only valid for transform types where transorm direction is implicitly /// given by the type (i.e. not C2C and not Z2Z) /// </summary> /// <param name="iodata"></param> public void Exec(CUdeviceptr iodata) { switch (_type) { case cufftType.R2C: res = CudaFFTNativeMethods.cufftExecR2C(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecR2C", res)); break; case cufftType.C2R: res = CudaFFTNativeMethods.cufftExecC2R(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecC2R", res)); break; case cufftType.D2Z: res = CudaFFTNativeMethods.cufftExecD2Z(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecD2Z", res)); break; case cufftType.Z2D: res = CudaFFTNativeMethods.cufftExecZ2D(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecZ2D", res)); break; default: throw new ArgumentException("For transformation not of type R2C, C2R, D2Z or Z2D, you must specify a transform direction."); } if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// Creates a FFT plan configuration of dimension rank, with sizes /// specified in the array <c>n</c>. The <c>batch</c> input parameter tells CUFFT how /// many transforms to configure in parallel. With this function, batched /// plans of any dimension may be created. (new API) /// </summary> /// <param name="handle">cufftHandle object</param> /// <param name="rank">Dimensionality of the transform (1, 2, or 3)</param> /// <param name="n">An array of size rank, describing the size of each dimension</param> /// <param name="batch">Batch size for this transform</param> /// <param name="type">Transform data type (e.g., C2C, as per other CUFFT calls)</param> /// <param name="size"></param> public CudaFFTPlanMany64(cufftHandle handle, int rank, long[] n, long batch, cufftType type, ref SizeT size) { _handle = handle; _rank = rank; _n = n; _batch = batch; _type = type; //optional: _inembed = null; _istride = 1; _idist = 0; _onembed = null; _ostride = 1; _odist = 0; res = CudaFFTNativeMethods.cufftMakePlanMany64(_handle, _rank, _n, _inembed, _istride, _idist, _onembed, _ostride, _odist, _type, _batch, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftMakePlanMany64", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
private static string GetErrorMessageFromCUResult(cufftResult error) { string message = string.Empty; switch (error) { case cufftResult.Success: message = "Any CUFFT operation is successful."; break; case cufftResult.InvalidPlan: message = "CUFFT is passed an invalid plan handle."; break; case cufftResult.AllocFailed: message = "CUFFT failed to allocate GPU memory."; break; case cufftResult.InvalidType: message = "The user requests an unsupported type."; break; case cufftResult.InvalidValue: message = "The user specifies a bad memory pointer."; break; case cufftResult.InternalError: message = "Used for all internal driver errors."; break; case cufftResult.ExecFailed: message = "CUFFT failed to execute an FFT on the GPU."; break; case cufftResult.SetupFailed: message = "The CUFFT library failed to initialize."; break; case cufftResult.InvalidSize: message = "The user specifies an unsupported FFT size."; break; case cufftResult.UnalignedData: message = "Input or output does not satisfy texture alignment requirements."; break; case cufftResult.IncompleteParameterList: message = "Missing parameter in call."; break; case cufftResult.InvalidDevice: message = "Plan creation and execution are on different device."; break; case cufftResult.ParseError: message = "Internal plan database error."; break; case cufftResult.NoWorkspace: message = "Workspace not initialized."; break; case cufftResult.NotImplemented: message = "Not implemented."; break; case cufftResult.LicenseError: message = "License error."; break; case cufftResult.NotSupported: message = "Not supported error."; break; default: break; } return(error.ToString() + ": " + message); }
private static string GetErrorMessageFromCUResult(cufftResult error) { string message = string.Empty; switch (error) { case cufftResult.Success: message = "Any CUFFT operation is successful."; break; case cufftResult.InvalidPlan: message = "CUFFT is passed an invalid plan handle."; break; case cufftResult.AllocFailed: message = "CUFFT failed to allocate GPU memory."; break; case cufftResult.InvalidType: message = "The user requests an unsupported type."; break; case cufftResult.InvalidValue: message = "The user specifies a bad memory pointer."; break; case cufftResult.InternalError: message = "Used for all internal driver errors."; break; case cufftResult.ExecFailed: message = "CUFFT failed to execute an FFT on the GPU."; break; case cufftResult.SetupFailed: message = "The CUFFT library failed to initialize."; break; case cufftResult.InvalidSize: message = "The user specifies an unsupported FFT size."; break; case cufftResult.UnalignedData: message = "Input or output does not satisfy texture alignment requirements."; break; case cufftResult.IncompleteParameterList: message = "Missing parameter in call."; break; case cufftResult.InvalidDevice: message = "Plan creation and execution are on different device."; break; case cufftResult.ParseError: message = "Internal plan database error."; break; case cufftResult.NoWorkspace: message = "Workspace not initialized."; break; case cufftResult.NotImplemented: message = "Not implemented."; break; case cufftResult.LicenseError: message = "License error."; break; default: break; } return error.ToString() + ": " + message; }
/// <summary> /// /// </summary> /// <param name="error"></param> public CudaFFTException(cufftResult error) : base(GetErrorMessageFromCUResult(error)) { this._cudaFFTError = error; }
/// <summary> /// Executes a CUFTT transorm as defined by the cufftType. /// This method does an in‐place transform. /// </summary> /// <param name="iodata"></param> /// <param name="direction">Only unsed for transformations where direction is not implicitly given by type</param> public void Exec(CUdeviceptr iodata, TransformDirection direction) { switch (_type) { case cufftType.R2C: res = CudaFFTNativeMethods.cufftExecR2C(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecR2C", res)); break; case cufftType.C2R: res = CudaFFTNativeMethods.cufftExecC2R(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecC2R", res)); break; case cufftType.C2C: res = CudaFFTNativeMethods.cufftExecC2C(_handle, iodata, iodata, direction); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecC2C", res)); break; case cufftType.D2Z: res = CudaFFTNativeMethods.cufftExecD2Z(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecD2Z", res)); break; case cufftType.Z2D: res = CudaFFTNativeMethods.cufftExecZ2D(_handle, iodata, iodata); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecZ2D", res)); break; case cufftType.Z2Z: res = CudaFFTNativeMethods.cufftExecZ2Z(_handle, iodata, iodata, direction); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftExecZ2Z", res)); break; default: break; } if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// Creates a new 1D FFT plan (new API) /// </summary> /// <param name="handle">cufftHandle object</param> /// <param name="nx">The transform size (e.g., 256 for a 256-point FFT)</param> /// <param name="type">The transform data type (e.g., C2C for complex to complex)</param> /// <param name="batch">Number of transforms of size nx</param> /// <param name="size"></param> public CudaFFTPlan1D(cufftHandle handle, int nx, cufftType type, int batch, ref SizeT size) { _handle = handle; _nx = nx; _type = type; _batch = batch; res = CudaFFTNativeMethods.cufftMakePlan1d(_handle, nx, type, batch, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftMakePlan1d", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// Associates a CUDA stream with a CUFFT plan. All kernel launches /// made during plan execution are now done through the associated /// stream, enabling overlap with activity in other streams (for example, /// data copying). The association remains until the plan is destroyed or /// the stream is changed with another call to SetStream(). /// </summary> /// <param name="stream">A valid CUDA stream created with cudaStreamCreate() (or 0 for the default stream)</param> public void SetStream(CUstream stream) { res = CudaFFTNativeMethods.cufftSetStream(_handle, stream); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftSetStream", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }
/// <summary> /// This call gives a more accurate estimate of the work area size required for a plan than /// cufftEstimate1d(), given the specified parameters, and taking into account any plan /// settings that may have been made. /// </summary> /// <returns></returns> public SizeT GetSize() { SizeT size = new SizeT(); res = CudaFFTNativeMethods.cufftGetSizeMany64(_handle, _rank, _n, _inembed, _istride, _idist, _onembed, _ostride, _odist, _type, _batch, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftGetSizeMany64", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); return size; }
/// <summary> /// Creates a FFT plan configuration of dimension rank, with sizes /// specified in the array <c>n</c>. The <c>batch</c> input parameter tells CUFFT how /// many transforms to configure in parallel. With this function, batched /// plans of any dimension may be created. (new API) /// </summary> /// <param name="handle">cufftHandle object</param> /// <param name="rank">Dimensionality of the transform (1, 2, or 3)</param> /// <param name="n">An array of size rank, describing the size of each dimension</param> /// <param name="batch">Batch size for this transform</param> /// <param name="type">Transform data type (e.g., C2C, as per other CUFFT calls)</param> /// <param name="inembed">See CUFFT Manual</param> /// <param name="istride">See CUFFT Manual</param> /// <param name="idist">See CUFFT Manual</param> /// <param name="onembed">See CUFFT Manual</param> /// <param name="ostride">See CUFFT Manual</param> /// <param name="odist">See CUFFT Manual</param> public CudaFFTPlanMany(cufftHandle handle, int rank, int[] n, int batch, cufftType type, int[] inembed, int istride, int idist, int[] onembed, int ostride, int odist) { SizeT size = new SizeT(); _handle = handle; _rank = rank; _n = n; _batch = batch; _type = type; //optional: _inembed = inembed; _istride = istride; _idist = idist; _onembed = onembed; _ostride = ostride; _odist = odist; res = CudaFFTNativeMethods.cufftMakePlanMany(_handle, _rank, _n, _inembed, _istride, _idist, _onembed, _ostride, _odist, _type, _batch, ref size); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cufftMakePlanMany", res)); if (res != cufftResult.Success) throw new CudaFFTException(res); }