C++ API

FFTX interfaces

The FFTX interfaces operate on constructs in namespace fftx. A multi-dimensional array is represented by an instance of struct array_t, which is defined by its domain as an instance of struct box_t, which in turn is defined by its corners, which are instances of struct point_t. An array instance also contains a pointer to the data, an instance of class global_ptr.

The class FFTXProblem defines an FFTX problem of a particular transform type of a particular size.

The documentation below is generated by doxygen.

fftx::point_t

template<int DIM>
struct point_t

A tuple of integer coordinates as an index into a ZDIM space.

Usually constructed with an array argument, such as: fftx::point_t<3> pt( {1, 2, 3} );

Public Functions

inline 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.

inline 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.

inline point_t<DIM> operator*(int scale) const

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

inline int product()

Returns the product of the components of this point_t.

inline point_t<DIM - 1> project() const

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

inline 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 inline point_t<DIM> Unit()

Returns a point_t with all components equal to one.

static inline 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 dimensions, defined by its low and high corners in index space.

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.

inline 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>
inline bool isInBox(point_t<DIM> a_pt, const box_t<DIM> &a_bx)

Returns true if the given point_t is contained in the given box_t.

template<int DIM>
inline size_t positionInBox(point_t<DIM> a_pt, const box_t<DIM> &a_bx)

Returns the position of the given point_t within the given box_t according to the ordering of points within it, starting from 0.

This function is the inverse of pointFromPositionBox() on the same box_t.

template<int DIM>
inline point_t<DIM> pointFromPositionBox(size_t a_ind, const box_t<DIM> &a_bx)

Returns the point_t that is at the given position in the given box_t, according to the ordering of points within it, starting from 0.

This function is the inverse of positionInBox() on the same box_t.

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

Non-owning view into a contiguous array of multi-dimensional data.

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, typename Func>
void forall(Func f, array_t<DIM, T> &array)

Applies the argument function to each element of the argument array, where the argument function f has the signaturevoid f(T& value, const fftx::point_t<DIM>& location).

The function argument is typically specified as a lambda expression, as in:

fftx::array_t<DIM, T>& array;
forall([varlist](T(&v), const fftx::point_t<DIM>& location)
{
   // ... assignment of v, or operations or function calls on v
}, array);
which loops through array over its domain, with v as array element at index location to be either assigned or have operations or functions called on it, and varlist (which may be empty) is a comma-separated list of previously declared variables that are used within the block.

template<int DIM, typename T1, typename T2, typename Func>
void forall(Func f, array_t<DIM, T1> &array, const array_t<DIM, T2> &array2)

Applies the argument function to each element of the two argument arrays, where the argument function f has the signaturevoid f(T1& value, const T2&, const point_t<DIM>& location).

The two arrays array and array2 must have the same domain.

The function argument is typically specified as a lambda expression, as in:

fftx::array_t<DIM, T1>& array;
const fftx::array_t<DIM, T2>& array2;
forall([varlist](T1(&v), T2(&v2), const fftx::point_t<DIM>& location)
{
   // ... assignment of v, or operations or function calls on v and v2
}, array, array2);
which loops through the common domain of array and array2, taking element v of array and element v2 of array2 at index location having operations or functions called on them and possibly assigning v, and varlist (which may be empty) is a comma-separated list of previously declared variables that are used within the block.

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 global pointer object. Can be used in place of upcxx::global_ptr.

Most of the FFTX API assumes that the user application code owns its primary data structures. This class encapsulates a user-space raw data pointer for use within our transforms.

The destructor does not delete the pointer. It is not reference-counting. It is not made to be unique. A global_ptr can be copied, moved, etc., like a basic C struct.

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 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 manner of specifying the pointer in each element of args depends on the backend:

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

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

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

  • for CPU, specify (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".