C++ API

Basic FFTX interfaces

The FFTX interfaces operate on constructs in namespace fftx.

struct fftx::array_t<int DIM, typename T> is the basic data holder structure defined on a DIM-dimensional array of data of type T on a fftx::box_t<DIM> and a fftx::global_ptr<T>, where:

FFTX classes for transforms

The class FFTXProblem defines an FFTX problem of a particular transform type of a particular size. It has several subclasses, each corresponding to a different type of transform:

The documentation below is generated by doxygen.

fftx::point_t

template<int DIM>
struct point_t

A tuple of integer coordinates in Z^DIM space.

This struct represents a point in a DIM-dimensional integer lattice. It provides coordinate access, assignment, and projection utilities.

Example usage:

fftx::point_t<3> pt({1, 2, 3});

Template Parameters:

DIM – Number of spatial dimensions.

Public Functions

void operator=(int a_default)

Assigns this point_t by setting the coordinates in every dimension to the argument.

inline int operator[](unsigned char a_id) const

Returns the value of the coordinate in the specified direction.

inline int &operator[](unsigned char a_id)

Returns a reference to the coordinate in the specified direction.

bool operator==(const point_t<DIM> &a_rhs) const

Returns true if all coordinates of this point_t are the same as the corresponding coordinates in the argument point_t, and false if any of the coordinates differ.

point_t<DIM> operator*(int scale) const

Modifies this point_t by multiplying all of its coordinates by the argument.

int product()

Returns the product of the components of this point_t.

point_t<DIM - 1> project() const

Returns a new point_t in one lower dimension, dropping the last coordinate value.

point_t<DIM - 1> projectC() const

Returns a new point_t in one lower dimension, dropping the first coordinate value.

inline point_t<DIM> flipped() const

Returns a point_t with the same coordinates as this point_t but with their ordering reversed.

Public Members

int x[DIM]

Array containing the coordinate in each direction.

Public Static Functions

static inline int dim()

Returns the dimension of this point_t.

static point_t<DIM> Unit()

Returns a point_t with all components equal to one.

static point_t<DIM> Zero()

Returns a point_t with all components equal to zero.

fftx::box_t

template<int DIM>
struct box_t

A rectangular domain on an integer lattice in DIM-dimensional integer space.

Represents a region defined by its low and high corners in Z^DIM.

Example usage:

fftx::box_t<3> domain ( fftx::point_t<3> ( { { 1, 1, 1 } } ),
                        fftx::point_t<3> ( { { mm, nn, kk } } ));

Template Parameters:

DIM – Number of spatial dimensions.

Public Functions

box_t() = default

Default constructor leaves box in an undefined state.

inline box_t(const point_t<DIM> &&a, const point_t<DIM> &&b)

Constructs a box having the given inputs as the low and high corners, respectively.

inline box_t(const point_t<DIM> &a, const point_t<DIM> &b)

Constructs a box having the given inputs as the low and high corners, respectively.

std::size_t size() const

Returns the number of points in the box in index space.

inline bool operator==(const box_t<DIM> &rhs) const

Returns true if the corners of this box are the same as the corners of the argument box.

inline point_t<DIM> extents() const

Returns a point_t object containing the length of the box in each coordinate direction.

inline box_t<DIM - 1> projectC() const

Returns a box_t object in one lower dimension, dropping the first coordinate value in both box_t::lo and box_t::hi.

Public Members

point_t<DIM> lo

The low corner of the box in index space.

point_t<DIM> hi

The high corner of the box in index space.

template<int DIM>
fftx::box_t<DIM> domainFromSize(const fftx::point_t<DIM> &a_size, const fftx::point_t<DIM> &a_offset = fftx::point_t<DIM>::Zero())

Returns a box having the dimensions of the first argument, with its lower corner in each direction being 1 plus the coordinate in that direction in the optional second argument.

template<int DIM>
inline fftx::point_t<DIM> shiftInBox(fftx::point_t<DIM> a_pt, fftx::point_t<DIM> a_shift, fftx::box_t<DIM> a_domain)

Returns a shifted point in a periodic domain.

The returned point is the input point a_pt shifted by a_shift and wrapped around if necessary to fit in a_domain.

fftx::array_t

template<int DIM, typename T>
struct array_t

A non-owning view into a contiguous array of DIM-dimensional data.

This class associates storage with a box_t<DIM> domain. The array holds values of type T, indexed by integer coordinates.

Example usage:

fftx::array_t<3,double> realFFTXHostArray(domain);

Template Parameters:
  • DIM – Number of spatial dimensions.

  • T – Type of values stored in the array.

Public Functions

inline array_t(global_ptr<T> &&p, const box_t<DIM> &a_box)

Strong constructor from an aliased global_ptr object. This constructor is an error when fftx::tracing is true.

inline array_t(const box_t<DIM> &a_box)

Constructor from a domain.

If fftx::tracing is true, then this constructor is a symbolic placeholder in a computational DAG that is translated into the code generator.

If fftx::tracing is false, then this constructor will allocate a global_ptr that is sized to hold a_box.size() elements of data of type T.

inline ~array_t()

Destructor, which deletes the local data if there is any.

Public Members

global_ptr<T> m_data

Pointer to a block in memory containing the data.

box_t<DIM> m_domain

The domain (box) on which the array is defined.

Friends

inline friend void swap(array_t &first, array_t &second)

Swaps the contents of first array and second array.

template<int DIM, typename T>
void copyArray(fftx::array_t<DIM, T> &a_arrOut, const fftx::array_t<DIM, T> &a_arrIn)

Sets the contents of the first array to the contents of the second array.

Both arrays a_arrIn and a_arrOut must be defined on the same domain.

template<int DIM, typename T>
void addArray(fftx::array_t<DIM, T> &a_arr, const fftx::array_t<DIM, T> &a_summand, T a_scalingSummand = scalarVal<T>(1.), T a_scalingOrig = scalarVal<T>(1.))

Increments the contents of the first array by the contents of the second array, optionally with scalar multiplication of each array:

Set

a_arr = a_scalingOrig * a_arr + a_scalingSummand * a_summand at each point.

Both arrays a_arr and a_summand must be defined on the same domain.

template<int DIM, typename T>
void multiplyByArray(fftx::array_t<DIM, T> &a_arr, const fftx::array_t<DIM, T> &a_multiplier)

Multiplies the contents of the first array by the contents of the second array, pointwise:

Set

a_arr = a_multiplier * a_arr at each point.

Both arrays a_arr and a_multiplier must be defined on the same domain.

template<int DIM, typename T>
void sumArrays(fftx::array_t<DIM, T> &a_sum, const fftx::array_t<DIM, T> &a_arr1, const fftx::array_t<DIM, T> &a_arr2, T a_scaling1 = scalarVal<T>(1.), T a_scaling2 = scalarVal<T>(1.))

Sets the contents of the first array to a sum of the contents of the second and third arrays, optionally with scalar multiplication of each input array:

Set

a_sum = a_scaling1 * a_arr1 + a_scaling2 * a_arr2 at each point.

The output array a_sum and the two input arrays a_arr1 and a_arr2 must all be defined on the same domain.

template<int DIM, typename T>
void diffArrays(fftx::array_t<DIM, T> &a_diff, const fftx::array_t<DIM, T> &a_arr1, const fftx::array_t<DIM, T> &a_arr2)

Sets the contents of the first array to the difference between the contents of second and third arrays:

Set

a_diff = a_arr1 - a_arr2 at each point.

The output array a_diff and the two input arrays a_arr1 and a_arr2 must all be defined on the same domain.

template<int DIM, typename T>
void productArrays(fftx::array_t<DIM, T> &a_prod, const fftx::array_t<DIM, T> &a_arr1, const fftx::array_t<DIM, T> &a_arr2)

Sets the contents of the first array to the pointwise product of the contents of second and third arrays:

Set

a_prod = a_arr1 * a_arr2 at each point.

The output array a_prod and the two input arrays a_arr1 and a_arr2 must all be defined on the same domain.

template<int DIM, typename T>
void setConstant(fftx::array_t<DIM, T> &a_arr, const T &a_val)

Sets every element of the argument array to the argument value.

template<int DIM>
void conjugateArray(fftx::array_t<DIM, std::complex<double>> &a_arr)

Modifies the argument array by setting every element to its complex conjugate.

template<int DIM, typename T>
void writeArray(fftx::array_t<DIM, T> &a_arr)

Writes out every element of the array, together with its DIM-dimensional index in the array and its position in the array starting from 0.

template<int DIM, typename T>
double absMaxArray(fftx::array_t<DIM, T> &a_arr)

Returns the maximum value of the std::abs function applied to elements of the argument array.

template<int DIM, typename T>
double absMaxDiffArray(fftx::array_t<DIM, T> &a_arr1, fftx::array_t<DIM, T> &a_arr2)

Returns the maximum value of the std::abs function applied to the differences in elements of the argument arrays with the same index.

The argument arrays a_arr1 and a_arr2 must be defined on the same domain.

template<int DIM, typename T>
void rotate(fftx::array_t<DIM, T> &a_arrOut, const fftx::array_t<DIM, T> &a_arrIn, int a_dim, int a_shift)

Sets the first argument array to a rotation of the second argument array. The rotation is specified by a periodic shift in dimension a_dim (in range 0 to DIM - 1) by amount a_shift.

The argument arrays a_arrOut and a_arrIn must be defined on the same domain.

template<int DIM, typename T>
void laplacian2periodic(fftx::array_t<DIM, T> &a_laplacian, const fftx::array_t<DIM, T> &a_arr)

Sets the first array to the second-order discrete Laplacian of the second array, which is taken as being periodic, with unit mesh spacing.

The argument arrays a_laplacian and a_arr must be defined on the same domain.

template<int DIM>
fftx::point_t<DIM> truncatedComplexDimensions(fftx::point_t<DIM> &a_size)

Returns the dimensions of a truncated complex array that is the result of a multidimensional discrete Fourier transform on a real-valued array having the dimensions in the argument.

template<int DIM, typename T_IN, typename T_OUT>
void symmetrizeHermitian(fftx::array_t<DIM, T_IN> &a_arrIn, fftx::array_t<DIM, T_OUT> &a_arrOut)

If T_IN is std::complex<double> and T_OUT is double, then modifies the first array where necessary to give it Hermitian symmetry.

A multidimensional discrete Fourier transform applied to a real-valued array gives a complex-valued array with Hermitian symmetry, and any complex-valued array with Hermitian symmetry can be the result of a multidimensional discrete Fourier transform applied to a real-valued array. When we perform tests of complex-to-real multimensional discrete Fourier transforms, we use arrays of random complex data that have been modified with this function so that the transform gives a real-valued result.

Hermitian symmetry requires that array elements in some positions be real, so this function sets the imaginary part of those elements to zero.

Hermitian symmetry also requires that array elements in some positions be the complex conjugate of array elements in some other positions, so this function sets those elements accordingly.

This function does not change the second argument array, but only checks that its domain is correct for a real-valued multidimensional array that is the result of a multidimensional discrete Fourier transform on the domain of the first array.

If T_IN is not std::complex<double> or T_OUT is not double, then this function has no effect.

fftx::global_ptr

template<typename T>
class global_ptr

A non-owning pointer to memory in a global or multi-device context.

This pointer wrapper does not manage ownership or lifetime, and may refer to memory allocated by the host application or externally shared across distributed systems or GPUs.

This class is functionally similar to upcxx::global_ptr, but used internally in FFTX to mark data as non-owning. It can be copied, moved, and reassigned like a raw pointer.

Template Parameters:

T – Element data type pointed to

Public Functions

inline global_ptr()

Default constructor with no data, no domain, no device.

inline global_ptr(T *ptr, int domain = 0, int device = 0)

Real strong constructor.

inline bool is_null() const

Returns true if this object has no data array assigned to it.

bool is_local() const

Returns true if this local compute context can successfully call the local() function and expect to get a pointer that can be dereferenced.

inline intrank_t where() const

Returns the compute domain that would answer “true” to isLocal(). Currently this just tests if the MPI rank matches my_rank.

inline int device() const

Returns the GPU device that this pointer associated with.

inline T *local()

Returns the raw pointer. This pointer can only be dereferenced if is_local() is true.

inline const T *local() const

Returns the raw pointer. This pointer can only be dereferenced if is_local() is true.

FFTXProblem

class FFTXProblem

Class for an FFTX problem defined by:

FFTXProblem is a pure virtual class; the functions randomProblemInstance() and semantics() need to be defined in any derived class.

Subclassed by BATCH1DDFTProblem, BATCH1DPRDFTProblem, IBATCH1DDFTProblem, IBATCH1DPRDFTProblem, IMDDFTProblem, IMDPRDFTProblem, MDDFTProblem, MDPRDFTProblem

Public Functions

inline FFTXProblem()

Default constructor that leaves FFTXProblem in an undefined state.

inline FFTXProblem(std::string name1)

Constructor that sets FFTXProblem::name only, to the argument.

inline FFTXProblem(const std::vector<void*> &args1)

Constructor that sets FFTXProblem::args only, to the argument.

inline FFTXProblem(const std::vector<int> &sizes1)

Constructor that sets FFTXProblem::sizes only, to the argument.

inline FFTXProblem(const std::vector<void*> &args1, const std::vector<int> &sizes1)

Constructor that sets FFTXProblem::args and FFTXProblem::sizes only, to the arguments.

inline FFTXProblem(const std::vector<int> sizes1, std::string name1)

Constructor that sets FFTXProblem::sizes and FFTXProblem::name only, to the arguments.

inline FFTXProblem(const std::vector<void*> &args1, const std::vector<int> &sizes1, std::string name1)

Constructor that sets FFTXProblem::args, FFTXProblem::sizes, and FFTXProblem::name, to the arguments.

inline void setSizes(const std::vector<int> &sizes1)

Sets FFTXProblem::sizes.

inline void setArgs(const std::vector<void*> &args1)

Sets FFTXProblem::args.

inline void setName(std::string name)

Sets FFTXProblem::name.

inline void transform()

Performs the transform.

inline float getTime()

Returns time taken by the GPU to perform the transform, in milliseconds.

inline ~FFTXProblem()

Destructor.

Public Members

std::vector<void*> args

Array of length 3 that contains the following.

  • args[0]: pointer to output array.

  • args[1]: pointer to input array.

  • args[2]: pointer to symbol array (not used by all transforms). If not used, then can be set to NULL.

The pointer format for each backend should be specified as follows:

  • CUDA: &ptr with CUdeviceptr ptr (or FFTX_DEVICE_PTR ptr if you have #include "fftxdevice_macros.h").

  • HIP: ptr with hipDeviceptr_t ptr (or FFTX_DEVICE_PTR ptr if you have #include "fftxdevice_macros.h").

  • SYCL: (void*) ptr with sycl::buffer<double> ptr.

  • CPU: (void*) ptr with double* ptr.

std::vector<int> sizes

Size of transform, as a std::vector<int> of length equal to the dimension, with the component in each coordinate direction representing the transform size in that direction.

std::string name

String that specifies the type of transform, which is one of the following.

  • "mddft": forward complex-to-complex 3D FFT

  • "imddft": inverse complex-to-complex 3D FFT

  • "mdprdft": real-to-complex 3D FFT

  • "imdprdft": complex-to-real 3D FFT

  • "rconv": real 3D convolution

  • "b1dft" or "dftbat": forward 1D batch FFT

  • "ib1dft" or "idftbat": inverse 1D batch FFT

MDDFTProblem

class MDDFTProblem : public FFTXProblem

Class for forward complex-to-complex 3D FFT.

FFTXProblem::args must be set to a std::vector<void*> of length 3, where

  • args[0] is a pointer to a complex output array of size the product of the dimensions in FFTXProblem::sizes;

  • args[1] is a pointer to a complex input array of size the product of the dimensions in FFTXProblem::sizes;

  • args[2] is not used and can be set to NULL.

FFTXProblem::sizes must be set to a std::vector<int> of length 3, containing the transform size in each coordinate dimension.

FFTXProblem::name must be set to "mddft".

IMDDFTProblem

class IMDDFTProblem : public FFTXProblem

Class for inverse complex-to-complex 3D FFT.

FFTXProblem::args must be set to a std::vector<void*> of length 3, where

  • args[0] is a pointer to a complex output array of size the product of the dimensions in FFTXProblem::sizes;

  • args[1] is a pointer to a complex input array of size the product of the dimensions in FFTXProblem::sizes;

  • args[2] is not used and can be set to NULL.

FFTXProblem::sizes must be set to a std::vector<int> of length 3, containing the transform size in each coordinate dimension.

FFTXProblem::name must be set to "imddft".

MDPRDFTProblem

class MDPRDFTProblem : public FFTXProblem

Class for real-to-complex 3D FFT.

FFTXProblem::args must be set to a std::vector<void*> of length 3, where

  • args[0] is a pointer to a complex output array of size the product of a truncated version of the dimensions in FFTXProblem::sizes: this will be sizes[0]*sizes[1]*(sizes[2]+1)/2;

  • args[1] is a pointer to a real input array of size the product of the dimensions in FFTXProblem::sizes;

  • args[2] is not used and can be set to NULL.

FFTXProblem::sizes must be set to a std::vector<int> of length 3, containing the transform size in each coordinate dimension.

FFTXProblem::name must be set to "mdprdft".

IMDPRDFTProblem

class IMDPRDFTProblem : public FFTXProblem

Class for complex-to-real 3D FFT.

FFTXProblem::args must be set to a std::vector<void*> of length 3, where

  • args[0] is a pointer to a real output array of size the product of the dimensions in FFTXProblem::sizes;

  • args[1] is a pointer to a complex input array of size the product of a truncated version of the dimensions in FFTXProblem::sizes: this will be sizes[0]*sizes[1]*(sizes[2]+1)/2;

  • args[2] is not used and can be set to NULL.

FFTXProblem::sizes must be set to a std::vector<int> of length 3, containing the transform size in each coordinate dimension.

FFTXProblem::name must be set to "imdprdft".

BATCH1DDFTProblem

class BATCH1DDFTProblem : public FFTXProblem

Class for forward complex-to-complex batched 1D FFT.

The specification allows both the input and the output to be distributed in either a sequential way (full first array in the batch followed by full second array, etc.) or a strided way (first element of every array in the batch followed by second element of every array, etc.).

FFTXProblem::args must be set to a std::vector<void*> of length 2, where

  • args[0] is a pointer to a complex output array of size the product of the batch size and FFT length: this array size is sizes[0] * sizes[1];

  • args[1] is a pointer to a complex input array of size the product of the batch size and FFT length: this array size is sizes[0] * sizes[1].

FFTXProblem::sizes must be set to a std::vector<int> of length 4, where:

  • sizes[0] is the length of the FFT;

  • sizes[1] is the batch size;

  • sizes[2] is 0 if the input is sequential, 1 if the input is strided;

  • sizes[3] is 0 if the output is sequential, 1 if the output is strided.

FFTXProblem::name must be set to "b1dft".

IBATCH1DDFTProblem

class IBATCH1DDFTProblem : public FFTXProblem

Class for inverse complex-to-complex batched 1D FFT.

The specification allows both the input and the output to be distributed in either a sequential way (full first array in the batch followed by full second array, etc.) or a strided way (first element of every array in the batch followed by second element of every array, etc.).

FFTXProblem::args must be set to a std::vector<void*> of length 2, where

  • args[0] is a pointer to a complex output array of size the product of the batch size and FFT length: this array size is sizes[0] * sizes[1];

  • args[1] is a pointer to a complex input array of size the product of the batch size and FFT length: this array size is sizes[0] * sizes[1].

FFTXProblem::sizes must be set to a std::vector<int> of length 4, where:

  • sizes[0] is the length of the FFT;

  • sizes[1] is the batch size;

  • sizes[2] is 0 if the input is sequential, 1 if the input is strided;

  • sizes[3] is 0 if the output is sequential, 1 if the output is strided.

FFTXProblem::name must be set to "ib1dft".

BATCH1DPRDFTProblem

class BATCH1DPRDFTProblem : public FFTXProblem

Class for real-to-complex batched 1D FFT.

The specification allows both the input and the output to be distributed in either a sequential way (full first array in the batch followed by full second array, etc.) or a strided way (first element of every array in the batch followed by second element of every array, etc.).

FFTXProblem::args must be set to a std::vector<void*> of length 2, where

  • args[0] is a pointer to a complex output array of size the product of the batch size and FFT output length: this array size is (sizes[0]+1)/2 * sizes[1];

  • args[1] is a pointer to a real input array of size the product of the batch size and FFT input length: this array size is sizes[0] * sizes[1].

FFTXProblem::sizes must be set to a std::vector<int> of length 4, where:

  • sizes[0] is the input length of the FFT;

  • sizes[1] is the batch size;

  • sizes[2] is 0 if the input is sequential, 1 if the input is strided;

  • sizes[3] is 0 if the output is sequential, 1 if the output is strided.

FFTXProblem::name must be set to "b1prdft".

IBATCH1DPRDFTProblem

class IBATCH1DPRDFTProblem : public FFTXProblem

Class for complex-to-real batched 1D FFT.

The specification allows both the input and the output to be distributed in either a sequential way (full first array in the batch followed by full second array, etc.) or a strided way (first element of every array in the batch followed by second element of every array, etc.).

FFTXProblem::args must be set to a std::vector<void*> of length 2, where

  • args[0] is a pointer to a real output array of size the product of the batch size and FFT output length: this array size is sizes[0] * sizes[1];

  • args[1] is a pointer to a complex input array of size the product of the batch size and FFT input length: this array size is (sizes[0]+1)/2 * sizes[1].

FFTXProblem::sizes must be set to a std::vector<int> of length 4, where:

  • sizes[0] is the output length of the FFT;

  • sizes[1] is the batch size;

  • sizes[2] is 0 if the input is sequential, 1 if the input is strided;

  • sizes[3] is 0 if the output is sequential, 1 if the output is strided.

FFTXProblem::name must be set to "ib1prdft".