1+ use std:: marker:: PhantomData ;
12use std:: mem:: MaybeUninit ;
23
34use cust:: memory:: GpuBuffer ;
45
56use crate :: { CufftError , IntoResult } ;
67
7- /// cuFFT transform type.
8- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
9- pub enum FftType {
10- /// Single-precision real-to-complex.
11- R2C ,
12- /// Single-precision complex-to-real.
13- C2R ,
14- /// Single-precision complex-to-complex.
15- C2C ,
16- /// Double-precision real-to-complex.
17- D2Z ,
18- /// Double-precision complex-to-real.
19- Z2D ,
20- /// Double-precision complex-to-complex.
21- Z2Z ,
8+ mod sealed {
9+ pub trait Sealed { }
2210}
2311
24- impl FftType {
25- fn into_raw ( self ) -> cufft_raw:: cufftType {
26- use cufft_raw:: cufftType:: * ;
27- match self {
28- FftType :: R2C => CUFFT_R2C ,
29- FftType :: C2R => CUFFT_C2R ,
30- FftType :: C2C => CUFFT_C2C ,
31- FftType :: D2Z => CUFFT_D2Z ,
32- FftType :: Z2D => CUFFT_Z2D ,
33- FftType :: Z2Z => CUFFT_Z2Z ,
34- }
12+ pub trait FftType : sealed:: Sealed {
13+ #[ doc( hidden) ]
14+ fn fft_type ( ) -> cufft_raw:: cufftType ;
15+ }
16+
17+ /// Marker type for single-precision complex-to-complex transforms.
18+ pub struct C2C ;
19+ /// Marker type for single-precision real-to-complex transforms.
20+ pub struct R2C ;
21+ /// Marker type for single-precision complex-to-real transforms.
22+ pub struct C2R ;
23+ /// Marker type for double-precision real-to-complex transforms.
24+ pub struct D2Z ;
25+ /// Marker type for double-precision complex-to-real transforms.
26+ pub struct Z2D ;
27+ /// Marker type for double-precision complex-to-complex transforms.
28+ pub struct Z2Z ;
29+
30+ impl sealed:: Sealed for C2C { }
31+ impl sealed:: Sealed for R2C { }
32+ impl sealed:: Sealed for C2R { }
33+ impl sealed:: Sealed for D2Z { }
34+ impl sealed:: Sealed for Z2D { }
35+ impl sealed:: Sealed for Z2Z { }
36+
37+ impl FftType for C2C {
38+ fn fft_type ( ) -> cufft_raw:: cufftType {
39+ cufft_raw:: cufftType:: CUFFT_C2C
40+ }
41+ }
42+
43+ impl FftType for R2C {
44+ fn fft_type ( ) -> cufft_raw:: cufftType {
45+ cufft_raw:: cufftType:: CUFFT_R2C
46+ }
47+ }
48+
49+ impl FftType for C2R {
50+ fn fft_type ( ) -> cufft_raw:: cufftType {
51+ cufft_raw:: cufftType:: CUFFT_C2R
52+ }
53+ }
54+
55+ impl FftType for D2Z {
56+ fn fft_type ( ) -> cufft_raw:: cufftType {
57+ cufft_raw:: cufftType:: CUFFT_D2Z
58+ }
59+ }
60+
61+ impl FftType for Z2D {
62+ fn fft_type ( ) -> cufft_raw:: cufftType {
63+ cufft_raw:: cufftType:: CUFFT_Z2D
64+ }
65+ }
66+
67+ impl FftType for Z2Z {
68+ fn fft_type ( ) -> cufft_raw:: cufftType {
69+ cufft_raw:: cufftType:: CUFFT_Z2Z
3570 }
3671}
3772
@@ -55,25 +90,26 @@ impl Direction {
5590
5691/// Wrapper for a `cufftHandle`.
5792#[ derive( Debug ) ]
58- pub struct FftPlan {
59- pub ( crate ) raw : cufft_raw:: cufftHandle ,
93+ pub struct FftPlan < T > {
94+ raw : cufft_raw:: cufftHandle ,
95+ _marker : PhantomData < T > ,
6096}
6197
62- impl FftPlan {
98+ impl < T : FftType > FftPlan < T > {
6399 /// Creates a 1-D FFT plan.
64100 ///
65101 /// # Reference
66102 ///
67103 /// [cufftPlan1d](https://docs.nvidia.com/cuda/cufft/index.html#cufftplan1d)
68- pub fn plan_1d ( nx : i32 , fft_type : FftType , batch : i32 ) -> Result < Self , CufftError > {
104+ pub fn plan_1d ( nx : i32 , batch : i32 ) -> Result < Self , CufftError > {
69105 let mut raw = MaybeUninit :: uninit ( ) ;
70106
71107 unsafe {
72- cufft_raw:: cufftPlan1d ( raw. as_mut_ptr ( ) , nx, fft_type. into_raw ( ) , batch)
73- . into_result ( ) ?;
108+ cufft_raw:: cufftPlan1d ( raw. as_mut_ptr ( ) , nx, T :: fft_type ( ) , batch) . into_result ( ) ?;
74109
75110 Ok ( Self {
76111 raw : raw. assume_init ( ) ,
112+ _marker : PhantomData ,
77113 } )
78114 }
79115 }
@@ -83,14 +119,15 @@ impl FftPlan {
83119 /// # Reference
84120 ///
85121 /// [cufftPlan2d](https://docs.nvidia.com/cuda/cufft/index.html#cufftplan2d)
86- pub fn plan_2d ( nx : i32 , ny : i32 , fft_type : FftType ) -> Result < Self , CufftError > {
122+ pub fn plan_2d ( nx : i32 , ny : i32 ) -> Result < Self , CufftError > {
87123 let mut raw = MaybeUninit :: uninit ( ) ;
88124
89125 unsafe {
90- cufft_raw:: cufftPlan2d ( raw. as_mut_ptr ( ) , nx, ny, fft_type. into_raw ( ) ) . into_result ( ) ?;
126+ cufft_raw:: cufftPlan2d ( raw. as_mut_ptr ( ) , nx, ny, T :: fft_type ( ) ) . into_result ( ) ?;
91127
92128 Ok ( Self {
93129 raw : raw. assume_init ( ) ,
130+ _marker : PhantomData ,
94131 } )
95132 }
96133 }
@@ -100,15 +137,15 @@ impl FftPlan {
100137 /// # Reference
101138 ///
102139 /// [cufftPlan3d](https://docs.nvidia.com/cuda/cufft/index.html#cufftplan3d)
103- pub fn plan_3d ( nx : i32 , ny : i32 , nz : i32 , fft_type : FftType ) -> Result < Self , CufftError > {
140+ pub fn plan_3d ( nx : i32 , ny : i32 , nz : i32 ) -> Result < Self , CufftError > {
104141 let mut raw = MaybeUninit :: uninit ( ) ;
105142
106143 unsafe {
107- cufft_raw:: cufftPlan3d ( raw. as_mut_ptr ( ) , nx, ny, nz, fft_type. into_raw ( ) )
108- . into_result ( ) ?;
144+ cufft_raw:: cufftPlan3d ( raw. as_mut_ptr ( ) , nx, ny, nz, T :: fft_type ( ) ) . into_result ( ) ?;
109145
110146 Ok ( Self {
111147 raw : raw. assume_init ( ) ,
148+ _marker : PhantomData ,
112149 } )
113150 }
114151 }
@@ -128,7 +165,6 @@ impl FftPlan {
128165 onembed : Option < & [ i32 ] > ,
129166 ostride : i32 ,
130167 odist : i32 ,
131- fft_type : FftType ,
132168 batch : i32 ,
133169 ) -> Result < Self , CufftError > {
134170 let mut raw = MaybeUninit :: uninit ( ) ;
@@ -147,18 +183,19 @@ impl FftPlan {
147183 onembed_ptr,
148184 ostride,
149185 odist,
150- fft_type. into_raw ( ) ,
186+ T :: fft_type ( ) ,
151187 batch,
152188 )
153189 . into_result ( ) ?;
154190
155191 Ok ( Self {
156192 raw : raw. assume_init ( ) ,
193+ _marker : PhantomData ,
157194 } )
158195 }
159196 }
160197
161- /// Set the CUDA stream for the plan.
198+ /// Sets the CUDA stream for the plan.
162199 ///
163200 /// # Reference
164201 ///
@@ -177,13 +214,15 @@ impl FftPlan {
177214 pub fn as_raw ( & self ) -> cufft_raw:: cufftHandle {
178215 self . raw
179216 }
217+ }
180218
219+ impl FftPlan < C2C > {
181220 /// Executes a single-precision C2C FFT.
182221 ///
183222 /// # Reference
184223 ///
185224 /// [cufftExecC2C](https://docs.nvidia.com/cuda/cufft/index.html#cufftexecc2c-and-cufftexecz2z)
186- pub fn exec_c2c (
225+ pub fn exec (
187226 & self ,
188227 idata : & impl GpuBuffer < cufft_raw:: cufftComplex > ,
189228 odata : & mut impl GpuBuffer < cufft_raw:: cufftComplex > ,
@@ -199,13 +238,15 @@ impl FftPlan {
199238 . into_result ( )
200239 }
201240 }
241+ }
202242
243+ impl FftPlan < R2C > {
203244 /// Executes a single-precision R2C FFT.
204245 ///
205246 /// # Reference
206247 ///
207248 /// [cufftExecR2C](https://docs.nvidia.com/cuda/cufft/index.html#cufftexecr2c-and-cufftexecd2z)
208- pub fn exec_r2c (
249+ pub fn exec (
209250 & self ,
210251 idata : & impl GpuBuffer < cufft_raw:: cufftReal > ,
211252 odata : & mut impl GpuBuffer < cufft_raw:: cufftComplex > ,
@@ -219,13 +260,15 @@ impl FftPlan {
219260 . into_result ( )
220261 }
221262 }
263+ }
222264
265+ impl FftPlan < C2R > {
223266 /// Executes a single-precision C2R inverse FFT.
224267 ///
225268 /// # Reference
226269 ///
227270 /// [cufftExecC2R](https://docs.nvidia.com/cuda/cufft/index.html#cufftexecc2r-and-cufftexecz2d)
228- pub fn exec_c2r (
271+ pub fn exec (
229272 & self ,
230273 idata : & impl GpuBuffer < cufft_raw:: cufftComplex > ,
231274 odata : & mut impl GpuBuffer < cufft_raw:: cufftReal > ,
@@ -239,13 +282,15 @@ impl FftPlan {
239282 . into_result ( )
240283 }
241284 }
285+ }
242286
287+ impl FftPlan < Z2Z > {
243288 /// Executes a double-precision Z2Z FFT.
244289 ///
245290 /// # Reference
246291 ///
247292 /// [cufftExecZ2Z](https://docs.nvidia.com/cuda/cufft/index.html#cufftexecc2c-and-cufftexecz2z)
248- pub fn exec_z2z (
293+ pub fn exec (
249294 & self ,
250295 idata : & impl GpuBuffer < cufft_raw:: cufftDoubleComplex > ,
251296 odata : & mut impl GpuBuffer < cufft_raw:: cufftDoubleComplex > ,
@@ -261,13 +306,15 @@ impl FftPlan {
261306 . into_result ( )
262307 }
263308 }
309+ }
264310
311+ impl FftPlan < D2Z > {
265312 /// Executes a double-precision D2Z FFT.
266313 ///
267314 /// # Reference
268315 ///
269316 /// [cufftExecD2Z](https://docs.nvidia.com/cuda/cufft/index.html#cufftexecr2c-and-cufftexecd2z)
270- pub fn exec_d2z (
317+ pub fn exec (
271318 & self ,
272319 idata : & impl GpuBuffer < cufft_raw:: cufftDoubleReal > ,
273320 odata : & mut impl GpuBuffer < cufft_raw:: cufftDoubleComplex > ,
@@ -281,13 +328,15 @@ impl FftPlan {
281328 . into_result ( )
282329 }
283330 }
331+ }
284332
333+ impl FftPlan < Z2D > {
285334 /// Executes a double-precision Z2D inverse FFT.
286335 ///
287336 /// # Reference
288337 ///
289338 /// [cufftExecZ2D](https://docs.nvidia.com/cuda/cufft/index.html#cufftexecc2r-and-cufftexecz2d)
290- pub fn exec_z2d (
339+ pub fn exec (
291340 & self ,
292341 idata : & impl GpuBuffer < cufft_raw:: cufftDoubleComplex > ,
293342 odata : & mut impl GpuBuffer < cufft_raw:: cufftDoubleReal > ,
@@ -303,12 +352,12 @@ impl FftPlan {
303352 }
304353}
305354
306- impl Drop for FftPlan {
355+ impl < T > Drop for FftPlan < T > {
307356 /// Destroys the plan.
308357 ///
309358 /// # Reference
310359 ///
311- /// [cufftDestroy) (https://docs.nvidia.com/cuda/cufft/index.html#cufftdestroy)
360+ /// [cufftDestroy] (https://docs.nvidia.com/cuda/cufft/index.html#cufftdestroy)
312361 fn drop ( & mut self ) {
313362 unsafe {
314363 let _ = cufft_raw:: cufftDestroy ( self . raw ) ;
0 commit comments