Branch data Line data Source code
1 : : #ifdef HAVE_DFTI
2 : : integer :: kk,ii,jj,sidx,cnt,dat,line,zplane,status,nthreads, iscale__,arr(2)
3 : : character(len=500) :: msg
4 : 5736024 : type(zpad_t) :: zpad
5 : : type(DFTI_DESCRIPTOR),pointer :: Desc1,Desc2,Desc3
6 : :
7 [ + + + + : 5738054 : iscale__ = merge(1, 0, isign == -1); if (present(iscale)) iscale__ = iscale
+ + + + ]
8 : :
9 : 5736024 : nthreads = xomp_get_num_threads(open_parallel=.TRUE.)
10 : :
11 : 5736024 : call zpad%init(nx, ny, nz, ldx, ldy, ldz, mgfft, gbound)
12 : :
13 : 2030 : select case (isign)
14 : : case (+1) ! G --> R
15 : : ! 1) Transform along x.
16 : : ! 1D transform of f(Gx,Gy,Gz) along Gx for each Gx-line intersecting the G-sphere
17 : :
18 : 2030 : status = DftiCreateDescriptor(Desc1, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, nx)
19 [ - + - + ]: 2030 : DFTI_CHECK(status)
20 : : !
21 : : ! TODO
22 : : ! this value was added in mkl version 11.0.
23 : : ! It's the only way to avoid side effect in mkl_set_num_threads thus making this routine thread safe
24 : : !status = DftiSetValue(Desc1, DFTI_THREAD_LIMIT, 1)
25 : 2030 : status = DftiSetValue(Desc1, DFTI_NUMBER_OF_USER_THREADS, nthreads)
26 : :
27 : 2030 : status = DftiCommitDescriptor(Desc1)
28 [ - + - + ]: 2030 : DFTI_CHECK(status)
29 : :
30 : : !$OMP PARALLEL DO PRIVATE(dat,line,jj,kk,sidx,status)
31 [ + + + + ]: 400722 : do cnt=0,(zpad%nlinex*ndat)-1
32 : 398692 : dat = 1 + cnt / zpad%nlinex
33 : 398692 : line = 1 + MOD(cnt, zpad%nlinex)
34 : 398692 : jj = zpad%linex2ifft_yz(1,line)
35 : 398692 : kk = zpad%linex2ifft_yz(2,line)
36 : 398692 : sidx = 1+ (jj-1)*ldx + (kk-1)*ldx*ldy + (dat-1) * ldx*ldy*ldz
37 : 398692 : status = DftiComputeBackward(Desc1, ff(sidx:)) ! Pass the base address.
38 [ - + - + ]: 400722 : DFTI_CHECK(status)
39 : : end do
40 : :
41 : 2030 : status = DftiFreeDescriptor(Desc1)
42 [ - + - + ]: 2030 : DFTI_CHECK(status)
43 : : !
44 : : ! 2) Transform along y:
45 : : ! nx 1D transforms of f(x,Gy,Gz) along Gy for each Gz plane intersecting the sphere.
46 : :
47 : 2030 : status = DftiCreateDescriptor(Desc2, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, ny)
48 [ - + - + ]: 2030 : DFTI_CHECK(status)
49 : :
50 : : !status = DftiSetValue(Desc2, DFTI_THREAD_LIMIT, 1)
51 : 2030 : status = DftiSetValue(Desc2, DFTI_NUMBER_OF_TRANSFORMS, nx)
52 : 2030 : status = DftiSetValue(Desc2, DFTI_INPUT_DISTANCE, 1)
53 : 2030 : arr(1) = 0
54 : 2030 : arr(2) = ldx
55 : 2030 : status = DftiSetValue(Desc2, DFTI_INPUT_STRIDES, arr)
56 : 2030 : status = DftiSetValue(Desc2, DFTI_NUMBER_OF_USER_THREADS, nthreads)
57 : :
58 : 2030 : status = DftiCommitDescriptor(Desc2)
59 [ - + - + ]: 2030 : DFTI_CHECK(status)
60 : :
61 : : !$OMP PARALLEL DO PRIVATE(dat,zplane,kk,sidx,status)
62 [ + + + + ]: 31862 : do cnt=0,(zpad%n_zplanes*ndat)-1
63 : 29832 : dat = 1 + cnt / zpad%n_zplanes
64 : 29832 : zplane = 1 + MOD(cnt, zpad%n_zplanes)
65 : 29832 : kk = zpad%zplane(1,zplane)
66 : 29832 : sidx = 1 + (kk-1)*ldx*ldy + (dat-1) *ldx*ldy*ldz
67 : 29832 : status = DftiComputeBackward(Desc2, ff(sidx:))
68 [ - + - + ]: 31862 : DFTI_CHECK(status)
69 : : end do
70 : :
71 : 2030 : status = DftiFreeDescriptor(Desc2)
72 [ - + - + ]: 2030 : DFTI_CHECK(status)
73 : : !
74 : : ! 3) Transform along z.
75 : : ! ldx*ldy 1D transforms of f(x,y,Gz) along Gz.
76 : : ! Note that we have to visit the entire augmented x-y plane!
77 : :
78 [ + + - + : 2030 : if (ndat==1 .or. nthreads==1 .or. MOD(ndat,nthreads)/=0) then
- - + + -
+ - - ]
79 : : !
80 : : ! Use MKL internal threading if single FFT or ndat is not divisible by nthreads
81 : : !status = DftiSetValue(Desc3, DFTI_THREAD_LIMIT, nthreads)
82 : 2030 : status = DftiCreateDescriptor(Desc3, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, nz)
83 [ - + - + ]: 2030 : DFTI_CHECK(status)
84 : :
85 : 2030 : status = DftiSetValue(Desc3, DFTI_NUMBER_OF_TRANSFORMS, ldx*ldy)
86 : 2030 : status = DftiSetValue(Desc3, DFTI_INPUT_DISTANCE, 1)
87 : : arr(1) = 0
88 : 2030 : arr(2) = ldx*ldy
89 : 2030 : status = DftiSetValue(Desc3, DFTI_INPUT_STRIDES, arr)
90 : :
91 : : ! Normalize the transform.
92 [ - + - + ]: 2030 : if (iscale__ /= 0) then
93 : 0 : status = DftiSetValue(Desc3, DFTI_BACKWARD_SCALE, one/(nx*ny*nz))
94 : : end if
95 : :
96 : 2030 : status = DftiCommitDescriptor(Desc3)
97 [ - + - + ]: 2030 : DFTI_CHECK(status)
98 : :
99 [ + + + + ]: 4102 : do dat=1,ndat
100 : 2072 : sidx = 1 + (dat-1) *ldx*ldy*ldz
101 : 2072 : status = DftiComputeBackward(Desc3, ff(sidx:))
102 [ - + - + ]: 4102 : DFTI_CHECK(status)
103 : : end do
104 : :
105 : 2030 : status = DftiFreeDescriptor(Desc3)
106 [ - + - + ]: 2030 : DFTI_CHECK(status)
107 : :
108 : : else
109 : : ! Split ndat transforms among the threads.
110 : : !call mkl_set_num_threads(1)
111 : 0 : status = DftiCreateDescriptor(Desc3, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, nz)
112 [ # # # # ]: 0 : DFTI_CHECK(status)
113 : :
114 : 0 : status = DftiSetValue(Desc3, DFTI_NUMBER_OF_TRANSFORMS, ldx*ldy)
115 : 0 : status = DftiSetValue(Desc3, DFTI_INPUT_DISTANCE, 1)
116 : : arr(1) = 0
117 : 0 : arr(2) = ldx*ldy
118 : 0 : status = DftiSetValue(Desc3, DFTI_INPUT_STRIDES, arr)
119 : 0 : status = DftiSetValue(Desc3, DFTI_NUMBER_OF_USER_THREADS, nthreads)
120 : : !status = DftiSetValue(Desc2, DFTI_THREAD_LIMIT, 1)
121 : :
122 : : ! Normalize the transform.
123 [ # # # # ]: 0 : if (iscale__ /= 0) then
124 : 0 : status = DftiSetValue(Desc3, DFTI_BACKWARD_SCALE, one/(nx*ny*nz))
125 : : end if
126 : :
127 : 0 : status = DftiCommitDescriptor(Desc3)
128 [ # # # # ]: 0 : DFTI_CHECK(status)
129 : :
130 : : !$OMP PARALLEL DO PRIVATE(sidx,status)
131 [ # # # # ]: 0 : do dat=1,ndat
132 : 0 : sidx = 1 + (dat-1) *ldx*ldy*ldz
133 : 0 : status = DftiComputeBackward(Desc3, ff(sidx:))
134 [ # # # # ]: 0 : DFTI_CHECK(status)
135 : : end do
136 : :
137 : 0 : status = DftiFreeDescriptor(Desc3)
138 [ # # # # ]: 0 : DFTI_CHECK(status)
139 : : end if
140 : :
141 : : case (-1) ! R --> G. Inverse of the algoritm used for G --> R
142 : : !
143 : : ! 1) Transform along z. Note We have to visit the entire augmented x-y plane!
144 [ + + - + : 5733994 : if (ndat==1 .or. nthreads==1 .or. MOD(ndat,nthreads)/=0) then
- - + + -
+ - - ]
145 : : !
146 : : ! Use MKL internal threading if single FFT or ndat is not divisible by nthreads
147 : 5733994 : status = DftiCreateDescriptor(Desc3, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, nz)
148 [ - + - + ]: 5733994 : DFTI_CHECK(status)
149 : :
150 : 5733994 : status = DftiSetValue(Desc3, DFTI_NUMBER_OF_TRANSFORMS, ldx*ldy)
151 : 5733994 : status = DftiSetValue(Desc3, DFTI_INPUT_DISTANCE, 1)
152 : 5733994 : arr(1) = 0
153 : 5733994 : arr(2) = ldx*ldy
154 : 5733994 : status = DftiSetValue(Desc3, DFTI_INPUT_STRIDES, arr)
155 : : !status = DftiSetValue(Desc3, DFTI_THREAD_LIMIT, nthreads)
156 : :
157 : 5733994 : status = DftiCommitDescriptor(Desc3)
158 [ - + - + ]: 5733994 : DFTI_CHECK(status)
159 : :
160 [ + + + + ]: 11468036 : do dat=1,ndat
161 : 5734042 : sidx = 1 + (dat-1) *ldx*ldy*ldz
162 : 5734042 : status = DftiComputeForward(Desc3, ff(sidx:))
163 [ - + - + ]: 11468036 : DFTI_CHECK(status)
164 : : end do
165 : :
166 : 5733994 : status = DftiFreeDescriptor(Desc3)
167 [ - + - + ]: 5733994 : DFTI_CHECK(status)
168 : : else
169 : : ! Split ndat transforms among the threads.
170 : 0 : status = DftiCreateDescriptor(Desc3, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, nz)
171 [ # # # # ]: 0 : DFTI_CHECK(status)
172 : :
173 : 0 : status = DftiSetValue(Desc3, DFTI_NUMBER_OF_TRANSFORMS, ldx*ldy)
174 : 0 : status = DftiSetValue(Desc3, DFTI_INPUT_DISTANCE, 1)
175 : 0 : arr(1) = 0
176 : 0 : arr(2) = ldx*ldy
177 : 0 : status = DftiSetValue(Desc3, DFTI_INPUT_STRIDES, arr)
178 : 0 : status = DftiSetValue(Desc3, DFTI_NUMBER_OF_USER_THREADS, nthreads)
179 : : !status = DftiSetValue(Desc3, DFTI_THREAD_LIMIT, 1)
180 : :
181 : 0 : status = DftiCommitDescriptor(Desc3)
182 [ # # # # ]: 0 : DFTI_CHECK(status)
183 : :
184 : : !$OMP PARALLEL DO PRIVATE(sidx,status)
185 [ # # # # ]: 0 : do dat=1,ndat
186 : 0 : sidx = 1 + (dat-1) *ldx*ldy*ldz
187 : 0 : status = DftiComputeForward(Desc3, ff(sidx:))
188 [ # # # # ]: 0 : DFTI_CHECK(status)
189 : : end do
190 : :
191 : 0 : status = DftiFreeDescriptor(Desc3)
192 [ # # # # ]: 0 : DFTI_CHECK(status)
193 : : end if
194 : : !
195 : : ! 2) Transform along y.
196 : :
197 : : !call mkl_set_num_threads(1)
198 : 5733994 : status = DftiCreateDescriptor(Desc2, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, ny)
199 [ - + - + ]: 5733994 : DFTI_CHECK(status)
200 : :
201 : : !status = DftiSetValue(Desc2, DFTI_THREAD_LIMIT, 1)
202 : 5733994 : status = DftiSetValue(Desc2, DFTI_NUMBER_OF_TRANSFORMS, nx)
203 : 5733994 : status = DftiSetValue(Desc2, DFTI_INPUT_DISTANCE, 1)
204 : 5733994 : arr(1) = 0
205 : 5733994 : arr(2) = ldx
206 : 5733994 : status = DftiSetValue(Desc2, DFTI_INPUT_STRIDES, arr)
207 : :
208 : 5733994 : status = DftiSetValue(Desc2, DFTI_NUMBER_OF_USER_THREADS, nthreads)
209 : :
210 : 5733994 : status = DftiCommitDescriptor(Desc2)
211 [ - + - + ]: 5733994 : DFTI_CHECK(status)
212 : :
213 : : !$OMP PARALLEL DO PRIVATE(dat,zplane,kk,sidx,status)
214 [ + + + + ]: 35475544 : do cnt=0,(zpad%n_zplanes*ndat)-1
215 : 29741550 : dat = 1 + cnt / zpad%n_zplanes
216 : 29741550 : zplane = 1 + MOD(cnt, zpad%n_zplanes)
217 : 29741550 : kk = zpad%zplane(1,zplane)
218 : 29741550 : sidx = 1 + ldx*ldy*(kk-1) + (dat-1) *ldx*ldy*ldz
219 : 29741550 : status = DftiComputeForward(Desc2, ff(sidx:))
220 [ - + - + ]: 35475544 : DFTI_CHECK(status)
221 : : end do
222 : :
223 : 5733994 : status = DftiFreeDescriptor(Desc2)
224 [ - + - + ]: 5733994 : DFTI_CHECK(status)
225 : : !
226 : : ! 3) Transform along x.
227 : : !
228 : 5733994 : status = DftiCreateDescriptor(Desc1, DEV_DFTI_PRECISION, DFTI_COMPLEX, 1, nx)
229 [ - + - + ]: 5733994 : DFTI_CHECK(status)
230 : :
231 : : !status = DftiSetValue(Desc1, DFTI_THREAD_LIMIT, 1)
232 : 5733994 : status = DftiSetValue(Desc1, DFTI_NUMBER_OF_USER_THREADS, nthreads)
233 : :
234 : : ! Normalize the transform.
235 [ + - + - ]: 5733994 : if (iscale__ /= 0) then
236 : 5733994 : status = DftiSetValue(Desc1, DFTI_FORWARD_SCALE, one/(nx*ny*nz))
237 : : end if
238 : :
239 : 5733994 : status = DftiCommitDescriptor(Desc1)
240 [ - + - + ]: 5733994 : DFTI_CHECK(status)
241 : :
242 : : !$OMP PARALLEL DO PRIVATE(dat,line,jj,kk,sidx,status)
243 [ + + + + ]: 117574079 : do cnt=0,(zpad%nlinex*ndat)-1
244 : 111840085 : dat = 1 + cnt / zpad%nlinex
245 : 111840085 : line = 1 + MOD(cnt, zpad%nlinex)
246 : 111840085 : jj = zpad%linex2ifft_yz(1,line)
247 : 111840085 : kk = zpad%linex2ifft_yz(2,line)
248 : 111840085 : sidx = 1+ (jj-1)*ldx + (kk-1)*ldx*ldy + (dat-1) * ldx*ldy*ldz
249 : 111840085 : status = DftiComputeForward(Desc1, ff(sidx:)) ! Pass the base address.
250 [ - + - + ]: 117574079 : DFTI_CHECK(status)
251 : : end do
252 : :
253 : 5733994 : status = DftiFreeDescriptor(Desc1)
254 [ - + - + ]: 5733994 : DFTI_CHECK(status)
255 : :
256 : : case default
257 [ + + - + : 5736024 : ABI_BUG("Wrong isign")
+ - ]
258 : : end select
259 : :
260 : 5736024 : call zpad%free()
261 : :
262 : : #else
263 : : ABI_ERROR("FFT_DFTI support not activated")
264 : : ABI_UNUSED((/nx,ny,nz,ldx,ldy,ldz,ndat,mgfft,isign,nthreads/))
265 : : ABI_UNUSED(gbound(1,1))
266 : : ABI_UNUSED(ff(1))
267 : : #endif
|