Highly Efficient FFT for Exascale: HeFFTe v2.4
Loading...
Searching...
No Matches
heffte_common.h
1/*
2 -- heFFTe --
3 Univ. of Tennessee, Knoxville
4 @date
5*/
6
7#ifndef HEFFFTE_COMMON_H
8#define HEFFFTE_COMMON_H
9
10#include "heffte_geometry.h"
11#include "heffte_trace.h"
12
13namespace heffte {
14
30namespace tag {
31
38struct cpu{};
45struct gpu{};
46
47}
48
53namespace backend {
54
59 template<typename location_tag> struct data_manipulator{};
60
65 template<> struct data_manipulator<tag::cpu> {
67 using stream_type = void*;
69 template<typename source_type, typename destination_type>
70 static void copy_n(void*, source_type const source[], size_t num_entries, destination_type destination[]){
71 std::copy_n(source, num_entries, destination);
72 }
74 template<typename source_type, typename destination_type>
75 static void copy_n(source_type const source[], size_t num_entries, destination_type destination[]){
76 std::copy_n(source, num_entries, destination);
77 }
79 template<typename source_type, typename destination_type>
80 static void copy_device_to_host(void*, source_type const source[], size_t num_entries, destination_type destination[]){
81 std::copy_n(source, num_entries, destination);
82 }
84 template<typename source_type, typename destination_type>
85 static void copy_device_to_device(void*, source_type const source[], size_t num_entries, destination_type destination[]){
86 std::copy_n(source, num_entries, destination);
87 }
89 template<typename source_type, typename destination_type>
90 static void copy_host_to_device(void*, source_type const source[], size_t num_entries, destination_type destination[]){
91 std::copy_n(source, num_entries, destination);
92 }
93 };
94
99 struct fftw{};
104 struct fftw_cos{};
109 struct fftw_sin{};
114 struct fftw_cos1{};
119 struct fftw_sin1{};
120
125 struct stock{};
130 struct stock_cos{};
135 struct stock_sin{};
140 struct stock_cos1{};
141
146 struct mkl{};
151 struct mkl_cos{};
156 struct mkl_sin{};
157
162 struct cufft{};
163
168 struct cufft_cos{};
173 struct cufft_sin{};
178 struct cufft_cos1{};
179
184 struct rocfft{};
189 struct rocfft_cos{};
194 struct rocfft_sin{};
199 struct rocfft_cos1{};
200
205 struct onemkl{};
210 struct onemkl_cos{};
215 struct onemkl_sin{};
216
225 template<typename tag>
226 struct is_enabled : std::false_type{};
227
241 template<typename T> using container = std::vector<T>;
242 };
243
248 template<typename backend_tag, typename = void>
249 struct uses_gpu : std::false_type{};
250
255 template<typename backend_tag>
257 typename std::enable_if<std::is_same<typename buffer_traits<backend_tag>::location, tag::gpu>::value, void>::type>
258 : std::true_type{};
259
264 template<typename backend_tag>
265 inline std::string name(){ return "unknown"; }
266
271 template<> inline std::string name<fftw>(){ return "fftw"; }
276 template<> inline std::string name<fftw_cos>(){ return "fftw-cos-type-II"; }
281 template<> inline std::string name<fftw_sin>(){ return "fftw-sin-type-II"; }
286 template<> inline std::string name<fftw_cos1>(){ return "fftw-cos-type-I"; }
291 template<> inline std::string name<fftw_sin1>(){ return "fftw-sin-type-I"; }
292
297 template<> inline std::string name<stock>(){ return "stock"; }
302 template<> inline std::string name<stock_cos>(){ return "stock-cos-type-II"; }
307 template<> inline std::string name<stock_sin>(){ return "stock-sin-type-II"; }
312 template<> inline std::string name<stock_cos1>(){ return "stock-cos-type-I"; }
313
318 template<> inline std::string name<mkl>(){ return "mkl"; }
323 template<> inline std::string name<mkl_cos>(){ return "mkl-cos"; }
328 template<> inline std::string name<mkl_sin>(){ return "mkl-sin"; }
333 template<> inline std::string name<cufft>(){ return "cufft"; }
338 template<> inline std::string name<cufft_cos>(){ return "cufft-cos-type-II"; }
343 template<> inline std::string name<cufft_sin>(){ return "cufft-sin-type-II"; }
348 template<> inline std::string name<cufft_cos1>(){ return "cufft-cos-type-I"; }
349
354 template<> inline std::string name<rocfft>(){ return "rocfft"; }
359 template<> inline std::string name<rocfft_cos>(){ return "rocfft-cos"; }
364 template<> inline std::string name<rocfft_sin>(){ return "rocfft-sin"; }
369 template<> inline std::string name<rocfft_cos1>(){ return "rocfft-sin"; }
370
375 template<> inline std::string name<onemkl>(){ return "onemkl"; }
380 template<> inline std::string name<onemkl_cos>(){ return "onemkl-cos"; }
385 template<> inline std::string name<onemkl_sin>(){ return "onemkl-sin"; }
386
391 template<> inline std::string name<tag::cpu>(){ return "cpu"; }
396 template<> inline std::string name<tag::gpu>(){ return "gpu"; }
397
407 template<typename backend_tag>
410 device_instance(void* = nullptr){}
412 virtual ~device_instance() = default;
414 void* stream(){ return nullptr; }
416 void* stream() const{ return nullptr; }
418 void synchronize_device() const{}
420 using stream_type = void*;
421 };
422
430 template<typename location_tag> struct default_backend{
432 using type = stock;
433 };
434
439 template<typename backend_tag> struct uses_fft_types : std::true_type{};
440
445 template<typename backend_tag, typename input, typename output, typename = void> struct check_types : std::false_type{};
446
451 template<typename backend_tag, typename input, typename output> struct check_types<backend_tag, input, output,
452 typename std::enable_if<uses_fft_types<backend_tag>::value and (
453 (std::is_same<input, float>::value and is_ccomplex<output>::value)
454 or (std::is_same<input, double>::value and is_zcomplex<output>::value)
455 or (is_ccomplex<input>::value and is_ccomplex<output>::value)
456 or (is_zcomplex<input>::value and is_zcomplex<output>::value)
457 )>::type> : std::true_type{};
458
463 template<> struct uses_fft_types<fftw_cos> : std::false_type{};
468 template<> struct uses_fft_types<fftw_sin> : std::false_type{};
473 template<> struct uses_fft_types<fftw_cos1> : std::false_type{};
478 template<> struct uses_fft_types<fftw_sin1> : std::false_type{};
483 template<> struct uses_fft_types<stock_cos> : std::false_type{};
488 template<> struct uses_fft_types<stock_sin> : std::false_type{};
493 template<> struct uses_fft_types<stock_cos1> : std::false_type{};
498 template<> struct uses_fft_types<mkl_cos> : std::false_type{};
503 template<> struct uses_fft_types<mkl_sin> : std::false_type{};
508 template<> struct uses_fft_types<cufft_cos> : std::false_type{};
513 template<> struct uses_fft_types<cufft_sin> : std::false_type{};
518 template<> struct uses_fft_types<cufft_cos1> : std::false_type{};
523 template<> struct uses_fft_types<rocfft_cos> : std::false_type{};
528 template<> struct uses_fft_types<rocfft_sin> : std::false_type{};
533 template<> struct uses_fft_types<rocfft_cos1> : std::false_type{};
538 template<> struct uses_fft_types<onemkl_cos> : std::false_type{};
543 template<> struct uses_fft_types<onemkl_sin> : std::false_type{};
544
549 template<typename backend_tag, typename input, typename output> struct check_types<backend_tag, input, output,
550 typename std::enable_if<not uses_fft_types<backend_tag>::value and (
551 (std::is_same<input, float>::value and std::is_same<output, float>::value)
552 or (std::is_same<input, double>::value and std::is_same<output, double>::value)
553 )>::type> : std::true_type{};
554
555}
556
562public:
564 virtual ~executor_base() = default;
566 virtual void forward(float[], float*) const{}
568 virtual void forward(double[], double*) const{}
570 virtual void backward(float[], float*) const{}
572 virtual void backward(double[], double*) const{}
574 virtual void forward(std::complex<float>[], std::complex<float>*) const{}
576 virtual void forward(std::complex<double>[], std::complex<double>*) const{}
578 virtual void backward(std::complex<float>[], std::complex<float>*) const{}
580 virtual void backward(std::complex<double>[], std::complex<double>*) const{}
582 virtual void forward(float const[], std::complex<float>[], std::complex<float>*) const{}
584 virtual void forward(double const[], std::complex<double>[], std::complex<double>*) const{}
586 virtual void backward(std::complex<float>[], float[], std::complex<float>*) const{}
588 virtual void backward(std::complex<double>[], double[], std::complex<double>*) const{}
590 virtual int box_size() const{ return 0; }
592 virtual size_t workspace_size() const{ return 0; }
594 virtual int complex_size() const{ return box_size(); }
595};
596
601template<typename backend_tag>
602struct align{
604 static float* pntr(float *p) {
605 if (std::is_same<backend_tag, backend::cufft>::value) {
606 return (reinterpret_cast<size_t>(p) % sizeof(std::complex<float>) == 0) ? p : p+1;
607 } else {
608 return p;
609 }
610 }
612 static double* pntr(double *p) {
613 if (std::is_same<backend_tag, backend::cufft>::value) {
614 return (reinterpret_cast<size_t>(p) % sizeof(std::complex<double>) == 0) ? p : p+1;
615 } else {
616 return p;
617 }
618 }
620 static std::complex<float>* pntr(std::complex<float> *p) {
621 if (std::is_same<backend_tag, backend::cufft>::value) {
622 return (reinterpret_cast<size_t>(p) % sizeof(std::complex<float>) == 0) ? p :
623 reinterpret_cast<std::complex<float>*>(reinterpret_cast<float*>(p) + 1);
624 } else {
625 return p;
626 }
627 }
629 static std::complex<double>* pntr(std::complex<double> *p) {
630 if (std::is_same<backend_tag, backend::cufft>::value) {
631 return (reinterpret_cast<size_t>(p) % sizeof(std::complex<double>) == 0) ? p :
632 reinterpret_cast<std::complex<double>*>(reinterpret_cast<double*>(p) + 1);
633 } else {
634 return p;
635 }
636 }
637};
638
643template<typename scalar_type>
644std::vector<scalar_type> make_buffer_container(void*, size_t size){
645 return std::vector<scalar_type>(size);
646}
647
652enum class direction {
654 forward,
657};
658
663template<typename> struct one_dim_backend{};
664
669template<typename backend_tag, typename index>
670static std::unique_ptr<typename one_dim_backend<backend_tag>::executor> make_executor(typename backend::device_instance<typename backend::buffer_traits<backend_tag>::location>::stream_type stream,
671 box3d<index> const box, int dimension){
672 return (box.empty()) ?
673 std::unique_ptr<typename one_dim_backend<backend_tag>::executor>() :
675}
680template<typename backend_tag, typename index>
681static std::unique_ptr<typename one_dim_backend<backend_tag>::executor> make_executor(typename backend::device_instance<typename backend::buffer_traits<backend_tag>::location>::stream_type stream,
682 box3d<index> const box, int dir1, int dir2){
683 return (box.empty()) ?
684 std::unique_ptr<typename one_dim_backend<backend_tag>::executor>() :
685 std::unique_ptr<typename one_dim_backend<backend_tag>::executor>(new typename one_dim_backend<backend_tag>::executor(stream, box, dir1, dir2));
686}
691template<typename backend_tag, typename index>
692static std::unique_ptr<typename one_dim_backend<backend_tag>::executor> make_executor(typename backend::device_instance<typename backend::buffer_traits<backend_tag>::location>::stream_type stream,
693 box3d<index> const box){
694 return (box.empty()) ?
695 std::unique_ptr<typename one_dim_backend<backend_tag>::executor>() :
696 std::unique_ptr<typename one_dim_backend<backend_tag>::executor>(new typename one_dim_backend<backend_tag>::executor(stream, box));
697}
702template<typename backend_tag, typename index>
703static std::unique_ptr<typename one_dim_backend<backend_tag>::executor_r2c> make_executor_r2c(typename backend::device_instance<typename backend::buffer_traits<backend_tag>::location>::stream_type stream,
704 box3d<index> const box, int dimension){
705 return (box.empty()) ?
706 std::unique_ptr<typename one_dim_backend<backend_tag>::executor_r2c>() :
707 std::unique_ptr<typename one_dim_backend<backend_tag>::executor_r2c>(new typename one_dim_backend<backend_tag>::executor_r2c(stream, box, dimension));
708}
709
714template<typename backend_tag>
715constexpr bool has_executor2d(){
716 // cosine transform variants don't have a 2D/3D version yet (due to the missing kernels)
717 // most backends are OK with the variants for 2D and 3D (stock isn't)
718 return not (std::is_same<backend_tag, backend::stock>::value
719 or std::is_same<backend_tag, backend::stock_cos>::value
720 or std::is_same<backend_tag, backend::mkl_cos>::value
721 or std::is_same<backend_tag, backend::cufft_cos>::value
722 or std::is_same<backend_tag, backend::rocfft_cos>::value
723 or std::is_same<backend_tag, backend::onemkl_cos>::value
724 or std::is_same<backend_tag, backend::stock_sin>::value
725 or std::is_same<backend_tag, backend::mkl_sin>::value
726 or std::is_same<backend_tag, backend::cufft_sin>::value
727 or std::is_same<backend_tag, backend::rocfft_sin>::value
728 or std::is_same<backend_tag, backend::onemkl_sin>::value
729 or std::is_same<backend_tag, backend::stock_cos1>::value
730 or std::is_same<backend_tag, backend::cufft_cos1>::value
731 or std::is_same<backend_tag, backend::rocfft_cos1>::value
732 );
733}
738template<typename backend_tag>
739constexpr bool has_executor3d(){
740 return not (std::is_same<backend_tag, backend::stock>::value
741 or std::is_same<backend_tag, backend::stock_cos>::value
742 or std::is_same<backend_tag, backend::mkl_cos>::value
743 or std::is_same<backend_tag, backend::cufft_cos>::value
744 or std::is_same<backend_tag, backend::rocfft_cos>::value
745 or std::is_same<backend_tag, backend::onemkl_cos>::value
746 or std::is_same<backend_tag, backend::stock_sin>::value
747 or std::is_same<backend_tag, backend::mkl_sin>::value
748 or std::is_same<backend_tag, backend::cufft_sin>::value
749 or std::is_same<backend_tag, backend::rocfft_sin>::value
750 or std::is_same<backend_tag, backend::onemkl_sin>::value
751 or std::is_same<backend_tag, backend::stock_cos1>::value
752 or std::is_same<backend_tag, backend::cufft_cos1>::value
753 or std::is_same<backend_tag, backend::rocfft_cos1>::value
754 );
755}
756
761template<typename> struct default_plan_options{};
762
763}
764
765#endif // #ifndef HEFFTE_COMMON_H
Base class for all backend executors.
Definition heffte_common.h:561
virtual void backward(std::complex< double >[], double[], std::complex< double > *) const
Backward FFT real-to-complex, double precision.
Definition heffte_common.h:588
virtual int complex_size() const
Return the size of the complex-box (r2c executors).
Definition heffte_common.h:594
virtual void backward(float[], float *) const
Backward r2r, single precision.
Definition heffte_common.h:570
virtual size_t workspace_size() const
Return the workspace of the size.
Definition heffte_common.h:592
virtual void forward(std::complex< double >[], std::complex< double > *) const
Forward FFT, double precision.
Definition heffte_common.h:576
virtual void forward(float const[], std::complex< float >[], std::complex< float > *) const
Forward FFT real-to-complex, single precision.
Definition heffte_common.h:582
virtual ~executor_base()=default
Virtual destructor.
virtual void forward(float[], float *) const
Forward r2r, single precision.
Definition heffte_common.h:566
virtual void forward(double[], double *) const
Forward r2r, double precision.
Definition heffte_common.h:568
virtual void backward(std::complex< double >[], std::complex< double > *) const
Backward FFT, double precision.
Definition heffte_common.h:580
virtual void forward(std::complex< float >[], std::complex< float > *) const
Forward FFT, single precision.
Definition heffte_common.h:574
virtual void backward(std::complex< float >[], float[], std::complex< float > *) const
Backward FFT real-to-complex, single precision.
Definition heffte_common.h:586
virtual void backward(std::complex< float >[], std::complex< float > *) const
Backward FFT, single precision.
Definition heffte_common.h:578
virtual void backward(double[], double *) const
Backward r2r, double precision.
Definition heffte_common.h:572
virtual int box_size() const
Return the size of the box.
Definition heffte_common.h:590
virtual void forward(double const[], std::complex< double >[], std::complex< double > *) const
Forward FFT real-to-complex, double precision.
Definition heffte_common.h:584
std::string name< tag::gpu >()
Indicates the name of the location tag.
Definition heffte_common.h:396
std::string name()
Returns the human readable name of the backend.
Definition heffte_common.h:265
std::vector< scalar_type > make_buffer_container(void *, size_t size)
Factory method to create new buffer container for the CPU backends.
Definition heffte_common.h:644
std::string name< tag::cpu >()
Indicates the name of the location tag.
Definition heffte_common.h:391
constexpr bool has_executor3d()
Defines whether the executor has a 3D version (single rank).
Definition heffte_common.h:739
constexpr bool has_executor2d()
Defines whether the executor has a 2D version (slabs).
Definition heffte_common.h:715
direction
Indicates the direction of the FFT (internal use only).
Definition heffte_common.h:652
@ backward
Inverse DFT transform.
@ forward
Forward DFT transform.
std::string name< cufft_cos >()
Returns the human readable name of the cuFFT backend.
Definition heffte_common.h:338
std::string name< cufft_sin >()
Returns the human readable name of the cuFFT backend.
Definition heffte_common.h:343
std::string name< cufft_cos1 >()
Returns the human readable name of the cuFFT backend.
Definition heffte_common.h:348
std::string name< cufft >()
Returns the human readable name of the cuFFT backend.
Definition heffte_common.h:333
std::string name< fftw_cos >()
Returns the human readable name of the FFTW backend.
Definition heffte_common.h:276
std::string name< fftw >()
Returns the human readable name of the FFTW backend.
Definition heffte_common.h:271
std::string name< fftw_sin >()
Returns the human readable name of the FFTW backend.
Definition heffte_common.h:281
std::string name< fftw_sin1 >()
Returns the human readable name of the FFTW backend.
Definition heffte_common.h:291
std::string name< fftw_cos1 >()
Returns the human readable name of the FFTW backend.
Definition heffte_common.h:286
std::string name< mkl_sin >()
Returns the human readable name of the MKL backend.
Definition heffte_common.h:328
std::string name< mkl >()
Returns the human readable name of the MKL backend.
Definition heffte_common.h:318
std::string name< mkl_cos >()
Returns the human readable name of the MKL backend.
Definition heffte_common.h:323
std::string name< onemkl >()
Returns the human readable name of the oneMKL backend.
Definition heffte_common.h:375
std::string name< onemkl_sin >()
Returns the human readable name of the oneMKL backend.
Definition heffte_common.h:385
std::string name< onemkl_cos >()
Returns the human readable name of the oneMKL backend.
Definition heffte_common.h:380
std::string name< rocfft_cos >()
Returns the human readable name of the rocFFT backend.
Definition heffte_common.h:359
std::string name< rocfft_cos1 >()
Returns the human readable name of the rocFFT backend.
Definition heffte_common.h:369
std::string name< rocfft >()
Returns the human readable name of the rocFFT backend.
Definition heffte_common.h:354
std::string name< rocfft_sin >()
Returns the human readable name of the rocFFT backend.
Definition heffte_common.h:364
std::string name< stock_cos1 >()
Returns the human readable name of the stock backend.
Definition heffte_common.h:312
std::string name< stock_sin >()
Returns the human readable name of the stock backend.
Definition heffte_common.h:307
std::string name< stock >()
Returns the human readable name of the stock backend.
Definition heffte_common.h:297
std::string name< stock_cos >()
Returns the human readable name of the stock backend.
Definition heffte_common.h:302
Namespace containing all HeFFTe methods and classes.
Definition heffte_backend_cuda.h:38
cuFFT requires that the input and output in R2C transforms are aligned to the complex type.
Definition heffte_common.h:602
static std::complex< float > * pntr(std::complex< float > *p)
Align for complex-float.
Definition heffte_common.h:620
static float * pntr(float *p)
Align for float.
Definition heffte_common.h:604
static double * pntr(double *p)
Align for double.
Definition heffte_common.h:612
static std::complex< double > * pntr(std::complex< double > *p)
Align for complex-double.
Definition heffte_common.h:629
Defines the container for the temporary buffers.
Definition heffte_common.h:237
tag::cpu location
Tags the raw-array location tag::cpu or tag::gpu, used by the packers.
Definition heffte_common.h:239
std::vector< T > container
Defines the container template to use for the temporary buffers in heffte::fft3d.
Definition heffte_common.h:241
Set to true/false type depending whether the types are compatible with the backend transform.
Definition heffte_common.h:445
Type-tag for the Cosine Transform type 1 using the cuFFT backend.
Definition heffte_common.h:178
Type-tag for the Cosine Transform using the cuFFT backend.
Definition heffte_common.h:168
Type-tag for the Sine Transform using the cuFFT backend.
Definition heffte_common.h:173
Type-tag for the cuFFT backend.
Definition heffte_common.h:162
static void copy_n(source_type const source[], size_t num_entries, destination_type destination[])
Wrapper around std::copy_n().
Definition heffte_common.h:75
static void copy_device_to_device(void *, source_type const source[], size_t num_entries, destination_type destination[])
Wrapper around std::copy_n().
Definition heffte_common.h:85
static void copy_device_to_host(void *, source_type const source[], size_t num_entries, destination_type destination[])
Wrapper around std::copy_n().
Definition heffte_common.h:80
static void copy_n(void *, source_type const source[], size_t num_entries, destination_type destination[])
Wrapper around std::copy_n().
Definition heffte_common.h:70
static void copy_host_to_device(void *, source_type const source[], size_t num_entries, destination_type destination[])
Wrapper around std::copy_n().
Definition heffte_common.h:90
Common data-transfer operations, must be specializes for each location (cpu/gpu).
Definition heffte_common.h:59
Defines inverse mapping from the location tag to a default backend tag.
Definition heffte_common.h:430
Holds the auxiliary variables needed by each backend.
Definition heffte_common.h:408
void synchronize_device() const
Syncs the execution with the queue, no-op in the CPU case.
Definition heffte_common.h:418
device_instance(void *=nullptr)
Empty constructor.
Definition heffte_common.h:410
void * stream()
Returns the nullptr.
Definition heffte_common.h:414
void * stream() const
Returns the nullptr (const case).
Definition heffte_common.h:416
virtual ~device_instance()=default
Default destructor.
Type-tag for the Cosine Transform type 1 using the FFTW backend.
Definition heffte_common.h:114
Type-tag for the Cosine Transform using the FFTW backend.
Definition heffte_common.h:104
Type-tag for the Sine Transform type 1 using the FFTW backend.
Definition heffte_common.h:119
Type-tag for the Sine Transform using the FFTW backend.
Definition heffte_common.h:109
Type-tag for the FFTW backend.
Definition heffte_common.h:99
Allows to define whether a specific backend interface has been enabled.
Definition heffte_common.h:226
Type-tag for the Cosine Transform using the MKL FFT backend.
Definition heffte_common.h:151
Type-tag for the Sine Transform using the MKL FFT backend.
Definition heffte_common.h:156
Type-tag for the MKL backend.
Definition heffte_common.h:146
Type-tag for the Cosine Transform using the oneMKL backend.
Definition heffte_common.h:210
Type-tag for the Sine Transform using the oneMKL backend.
Definition heffte_common.h:215
Type-tag for the oneMKL backend.
Definition heffte_common.h:205
Type-tag for the Cosine Transform of type 1 using the rocFFT backend.
Definition heffte_common.h:199
Type-tag for the Cosine Transform using the rocFFT backend.
Definition heffte_common.h:189
Type-tag for the Sine Transform using the rocFFT backend.
Definition heffte_common.h:194
Type-tag for the rocFFT backend.
Definition heffte_common.h:184
Type-tag for the Cosine Transform type 1 using the stock FFT backend.
Definition heffte_common.h:140
Type-tag for the Cosine Transform using the stock FFT backend.
Definition heffte_common.h:130
Type-tag for the Sine Transform using the stock FFT backend.
Definition heffte_common.h:135
Type-tag for the stock FFT backend.
Definition heffte_common.h:125
Defines whether the backend accepts the standard FFT real-complex or complex-complex transform.
Definition heffte_common.h:439
Struct that specializes to true type if the location of the backend is on the gpu (false type otherwi...
Definition heffte_common.h:249
Defines a set of default plan options for a given backend.
Definition heffte_common.h:761
Indicates the structure that will be used by the fft backend.
Definition heffte_common.h:663
Wrapper around cufftHandle plans, set for float or double complex.
Definition heffte_backend_cuda.h:346
Indicates the use of cpu backend and that all input/output data and arrays will be bound to the cpu.
Definition heffte_common.h:38
Indicates the use of gpu backend and that all input/output data and arrays will be bound to the gpu d...
Definition heffte_common.h:45