HILA
Loading...
Searching...
No Matches
fft.cpp
1/// Static variables and functions for hila fft routines
2
3
4#include "plumbing/defs.h"
5#include "plumbing/timing.h"
6#include "plumbing/fft.h"
7
8
9hila::timer fft_timer("FFT total time");
10hila::timer fft_plan_timer(" FFT plan");
11hila::timer pencil_MPI_timer(" MPI for pencils");
12hila::timer fft_execute_timer(" FFT execute");
13hila::timer pencil_reshuffle_timer(" pencil reshuffle");
14hila::timer fft_buffer_timer(" copy fft buffers");
15hila::timer pencil_collect_timer(" copy pencils");
16hila::timer pencil_save_timer(" save pencils");
17
18hila::timer binning_timer("bin field time");
19
20// a couple of global fft variables - easiest this way
21std::vector<pencil_struct> hila_pencil_comms[NDIM];
22unsigned hila_fft_my_columns[NDIM]; // how many columns does this node take care of
23size_t pencil_recv_buf_size[NDIM];
24
25// static variable to hold fft plans
26#if (defined(HIP) || defined(CUDA)) && !defined(HILAPP)
27hila_saved_fftplan_t hila_saved_fftplan;
28#endif
29
30// Delete saved plans if required - no-op for non-gpu
31void FFT_delete_plans() {
32#if (defined(HIP) || defined(CUDA)) && !defined(HILAPP)
33 hila_saved_fftplan.delete_plans();
34#endif
35}
36
37
38
39size_t pencil_get_buffer_offsets(const Direction dir, const size_t elements,
40 CoordinateVector &offset, CoordinateVector &nmin) {
41
42 offset[dir] = 1;
43 nmin = lattice.mynode.min;
44
45 size_t element_offset = lattice.mynode.size[dir];
46 size_t s = element_offset * elements;
47
48 foralldir(d) if (d != dir) {
49 offset[d] = s;
50 s *= lattice.mynode.size[d];
51 }
52
53 return element_offset;
54}
55
56/// THis is to be called before fft to Direction dir
57
58
59/////////////////////////////////////////////////////////////////////////////////////
60
61void init_pencil_direction(Direction dir) {
62
63 if (hila_pencil_comms[dir].size() == 0) {
64 // basic structs not yet set, do it here
65
66 hila_pencil_comms[dir].resize(lattice.nodes.n_divisions[dir]);
67
68 int nodenumber = 0;
69 for (const node_info &n : lattice.nodes.nodelist) {
70 bool is_in_column = true;
71 foralldir(d) if (d != dir && n.min[d] != lattice.mynode.min[d]) {
72 is_in_column = false;
73 break; // breaks out of foralldir
74 }
75
76 // store the nodes in the hila_pencil_comms -list in the right order -
77 // nodes may be reordered by some weird layout
78 if (is_in_column) {
79 pencil_struct fn;
80 fn.node = nodenumber;
81 fn.size_to_dir = n.size[dir];
82 for (int i = 0; i < lattice.nodes.n_divisions[dir]; i++) {
83 if (n.min[dir] == lattice.nodes.divisors[dir][i]) {
84 hila_pencil_comms[dir].at(i) = fn;
85 }
86 }
87 }
88 ++nodenumber;
89 }
90
91 size_t total_columns = lattice.mynode.sites / lattice.mynode.size[dir];
92
93 size_t nodes = hila_pencil_comms[dir].size();
94
95 // column offset and number are used for sending
96 size_t i = 0;
97 for (pencil_struct &fn : hila_pencil_comms[dir]) {
98 fn.column_offset =
99 ((i * total_columns) / nodes) * lattice.mynode.size[dir];
100 fn.column_number = (((i + 1) * total_columns) / nodes) -
101 fn.column_offset / lattice.mynode.size[dir];
102
103 if (fn.node == hila::myrank()) {
104 hila_fft_my_columns[dir] = fn.column_number;
105 }
106 i++;
107 }
108
109 pencil_recv_buf_size[dir] = 0;
110
111 for (pencil_struct &fn : hila_pencil_comms[dir]) {
112 fn.recv_buf_size = hila_fft_my_columns[dir] * fn.size_to_dir;
113
114 // how big array?
115 if (fn.node != hila::myrank())
116 pencil_recv_buf_size[dir] += fn.recv_buf_size;
117 }
118
119 } // setup
120}
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
Definition coordinates.h:34
This file defines all includes for HILA.
int myrank()
rank of this node
Definition com_mpi.cpp:235
useful information about a node
Definition lattice.h:48