OpenCLFFT3D.h 6.47 KB
Newer Older
Peter Eastman's avatar
Peter Eastman committed
1
2
3
4
5
6
7
8
9
10
11
#ifndef __OPENMM_OPENCLFFT3D_H__
#define __OPENMM_OPENCLFFT3D_H__

/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the OpenMM molecular simulation toolkit originating from   *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
Peter Eastman's avatar
Peter Eastman committed
12
 * Portions copyright (c) 2009-2023 Stanford University and the Authors.      *
Peter Eastman's avatar
Peter Eastman committed
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * This program is free software: you can redistribute it and/or modify       *
 * it under the terms of the GNU Lesser General Public License as published   *
 * by the Free Software Foundation, either version 3 of the License, or       *
 * (at your option) any later version.                                        *
 *                                                                            *
 * This program is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 * GNU Lesser General Public License for more details.                        *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
 * -------------------------------------------------------------------------- */

Peter Eastman's avatar
Peter Eastman committed
30
31
32
33
34
35
#define USE_VKFFT

#ifdef USE_VKFFT
#define VKFFT_BACKEND 3
#include "vkFFT.h"
#endif
Peter Eastman's avatar
Peter Eastman committed
36
37
38
39
#include "OpenCLArray.h"

namespace OpenMM {

Peter Eastman's avatar
Peter Eastman committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifdef USE_VKFFT
/**
 * This class performs three dimensional Fast Fourier Transforms.  It uses the
 * VkFFT library (https://github.com/DTolm/VkFFT).
 * <p>
 * This class is most efficient when the size of each dimension is a product of
 * small prime factors: 2, 3, 5, 7, 11, and 13.  You can call findLegalDimension()
 * to determine the smallest size that satisfies this requirement and is greater
 * than or equal to a specified minimum size.
 * <p>
 * Note that this class performs an unnormalized transform.  That means that if you perform
 * a forward transform followed immediately by an inverse transform, the effect is to
 * multiply every value of the original data set by the total number of data points.
 */
#else
Peter Eastman's avatar
Peter Eastman committed
55
56
57
58
59
60
61
62
63
/**
 * This class performs three dimensional Fast Fourier Transforms.  It is based on the
 * mixed radix algorithm described in
 * <p>
 * Takahashi, D. and Kanada, Y., "High-Performance Radix-2, 3 and 5 Parallel 1-D Complex
 * FFT Algorithms for Distributed-Memory Parallel Computers."  Journal of Supercomputing,
 * 15, 207–228 (2000).
 * <p>
 * This class places certain restrictions on the allowed dimensions of the grid.  First,
64
 * the size of each dimension may have no prime factors other than 2, 3, 5, and 7.  You
Peter Eastman's avatar
Peter Eastman committed
65
66
67
68
69
70
71
72
73
74
 * can call findLegalDimension() to determine the smallest size that satisfies this
 * requirement and is greater than or equal to a specified minimum size.  Second, the size
 * of each dimension must be small enough to compute each 1D transform entirely in local
 * memory with one work unit per data point.  This will vary between platforms, but is
 * typically at least 512.
 * <p>
 * Note that this class performs an unnormalized transform.  That means that if you perform
 * a forward transform followed immediately by an inverse transform, the effect is to
 * multiply every value of the original data set by the total number of data points.
 */
Peter Eastman's avatar
Peter Eastman committed
75
#endif
Peter Eastman's avatar
Peter Eastman committed
76

77
class OPENMM_EXPORT_COMMON OpenCLFFT3D {
Peter Eastman's avatar
Peter Eastman committed
78
public:
Peter Eastman's avatar
Peter Eastman committed
79
80
81
82
83
84
85
    /**
     * Create an OpenCLFFT3D object for performing transforms of a particular size.
     *
     * @param context the context in which to perform calculations
     * @param xsize   the first dimension of the data sets on which FFTs will be performed
     * @param ysize   the second dimension of the data sets on which FFTs will be performed
     * @param zsize   the third dimension of the data sets on which FFTs will be performed
86
     * @param realToComplex  if true, a real-to-complex transform will be done.  Otherwise, it is complex-to-complex.
Peter Eastman's avatar
Peter Eastman committed
87
     */
88
    OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize, bool realToComplex=false);
Peter Eastman's avatar
Peter Eastman committed
89
90
91
#ifdef USE_VKFFT
    ~OpenCLFFT3D();
#endif
Peter Eastman's avatar
Peter Eastman committed
92
    /**
Peter Eastman's avatar
Peter Eastman committed
93
94
     * Perform a Fourier transform.  The transform cannot be done in-place: the input and output
     * arrays must be different.  Also, the input array is used as workspace, so its contents
95
96
     * are destroyed.  This also means that both arrays must be large enough to hold complex values,
     * even when performing a real-to-complex transform.
97
98
99
     * <p>
     * When performing a real-to-complex transform, the output data is of size xsize*ysize*(zsize/2+1)
     * and contains only the non-redundant elements.
Peter Eastman's avatar
Peter Eastman committed
100
     *
Peter Eastman's avatar
Peter Eastman committed
101
102
     * @param in       the data to transform, ordered such that in[x*ysize*zsize + y*zsize + z] contains element (x, y, z)
     * @param out      on exit, this contains the transformed data
Peter Eastman's avatar
Peter Eastman committed
103
104
     * @param forward  true to perform a forward transform, false to perform an inverse transform
     */
105
    void execFFT(OpenCLArray& in, OpenCLArray& out, bool forward = true);
Peter Eastman's avatar
Peter Eastman committed
106
107
    /**
     * Get the smallest legal size for a dimension of the grid (that is, a size with no prime
108
     * factors other than 2, 3, 5, and 7).
Peter Eastman's avatar
Peter Eastman committed
109
110
111
112
     *
     * @param minimum   the minimum size the return value must be greater than or equal to
     */
    static int findLegalDimension(int minimum);
Peter Eastman's avatar
Peter Eastman committed
113
114
private:
    int xsize, ysize, zsize;
115
    int xthreads, ythreads, zthreads;
116
    bool packRealAsComplex;
Peter Eastman's avatar
Peter Eastman committed
117
    OpenCLContext& context;
Peter Eastman's avatar
Peter Eastman committed
118
119
120
121
#ifdef USE_VKFFT
    VkFFTApplication app;
#else
    cl::Kernel createKernel(int xsize, int ysize, int zsize, int& threads, int axis, bool forward, bool inputIsReal);
Peter Eastman's avatar
Peter Eastman committed
122
    cl::Kernel xkernel, ykernel, zkernel;
123
124
    cl::Kernel invxkernel, invykernel, invzkernel;
    cl::Kernel packForwardKernel, unpackForwardKernel, packBackwardKernel, unpackBackwardKernel;
Peter Eastman's avatar
Peter Eastman committed
125
#endif
Peter Eastman's avatar
Peter Eastman committed
126
127
128
129
};

} // namespace OpenMM

130
#endif // __OPENMM_OPENCLFFT3D_H__