21 use,
intrinsic :: iso_fortran_env
52 class(mesh_t),
intent(in) :: mesh
53 real(real64),
intent(in) :: g_vector(:)
54 complex(real64),
intent(out) :: state(:)
59 assert(
size(g_vector) ==
size(mesh%chi, 1))
60 assert(
size(state) == mesh%np)
64 state(ip) =
exp(two_pi_i * dot_product(g_vector, mesh%chi(:, ip)))
72 type(namespace_t),
intent(in) :: namespace
74 integer,
parameter :: batch_size = 4
76 integer,
parameter :: count_partial = 3
78 real(real64),
parameter :: tolerance = 1.0e-10_real64
80 real(real64),
parameter :: reinit_q_value = 1e9_real64
82 type(electrons_t),
pointer :: sys
83 type(poisson_t) :: psolver_single, psolver_batch, psolver_batch_last
84 type(poisson_t) :: psolver_real_batch, psolver_real_single
85 type(fourier_space_op_t) :: coulb
86 complex(real64),
allocatable :: rho_batch(:, :), pot(:), pot_batch(:, :), pot_partial(:, :), pot_batch_last(:, :)
87 complex(real64),
allocatable :: pot_real_batch(:, :), pot_real(:)
88 real(real64),
allocatable :: diff(:), max_abs_diff(:), mean_diff(:), max_abs_diff_partial(:), max_abs_diff_last(:)
89 real(real64),
allocatable :: max_abs_diff_real(:)
91 real(real64) :: qred(3)
94 real(real64),
parameter :: dG(3, batch_size) = reshape([ &
103 call messages_write(
'Info: Testing batched FFT Poisson solve for periodic k-point pair products')
107 qred = [0.25_real64, 0.125_real64, 0.0_real64]
114 safe_allocate(rho_batch(1:sys%gr%np, 1:batch_size))
115 do ipair = 1, batch_size
122 call poisson_init(psolver_batch, namespace, sys%space, sys%gr%der, sys%mc, sys%gr%stencil, &
123 sys%st%qtot, label=
'Pair-product Poisson batch size 4', solver=
poisson_fft, verbose=.false., &
124 force_serial=.
true., force_cmplx=.
true., fft_batch_size=batch_size)
128 safe_allocate(coulb%qq(1:sys%space%dim))
129 coulb%qq = reinit_q_value
132 safe_allocate(pot_batch(1:sys%gr%np, 1:batch_size))
137 safe_allocate(pot_partial(1:sys%gr%np, 1:count_partial))
146 call poisson_init(psolver_batch_last, namespace, sys%space, sys%gr%der, sys%mc, sys%gr%stencil, &
147 sys%st%qtot, label=
'Pair-product Poisson batch size 4 (batch-last)', solver=
poisson_fft, verbose=.false., &
148 force_serial=.
true., force_cmplx=.
true., fft_batch_size=batch_size, fft_batch_axis=4)
149 safe_allocate(pot_batch_last(1:sys%gr%np, 1:batch_size))
162 call poisson_init(psolver_real_batch, namespace, sys%space, sys%gr%der, sys%mc, sys%gr%stencil, &
163 sys%st%qtot, label=
'Pair-product Poisson real cube batch size 4', solver=
poisson_fft, &
164 verbose=.false., force_serial=.
true., force_cmplx=.false., fft_batch_size=batch_size)
165 safe_allocate(pot_real_batch(1:sys%gr%np, 1:batch_size))
169 write(
message(1),
'(a)')
'Test Poisson FFT batching: Performed batch solve'
175 call poisson_init(psolver_single, namespace, sys%space, sys%gr%der, sys%mc, sys%gr%stencil, &
176 sys%st%qtot, label=
'Pair-product Poisson batch size 1', solver=
poisson_fft, verbose=.false., &
177 force_serial=.
true., force_cmplx=.
true., fft_batch_size=1)
180 call poisson_init(psolver_real_single, namespace, sys%space, sys%gr%der, sys%mc, sys%gr%stencil, &
181 sys%st%qtot, label=
'Pair-product Poisson real cube batch size 1', solver=
poisson_fft, &
182 verbose=.false., force_serial=.
true., force_cmplx=.false., fft_batch_size=1)
184 safe_allocate(pot(1:sys%gr%np))
185 safe_allocate(pot_real(1:sys%gr%np))
186 safe_allocate(diff(1:sys%gr%np))
187 safe_allocate(mean_diff(1:batch_size))
188 safe_allocate(max_abs_diff(1:batch_size))
189 safe_allocate(max_abs_diff_partial(1:count_partial))
190 safe_allocate(max_abs_diff_last(1:batch_size))
191 safe_allocate(max_abs_diff_real(1:batch_size))
193 do ipair = 1, batch_size
195 call zpoisson_solve(psolver_single, namespace, pot, rho_batch(:, ipair), all_nodes=.false., kernel=coulb)
196 diff = abs(pot_batch(:, ipair) - pot(:))
197 mean_diff(ipair) = sum(diff)/real(
size(diff), real64)
198 max_abs_diff(ipair) = maxval(diff)
200 max_abs_diff_last(ipair) = maxval(abs(pot_batch_last(:, ipair) - pot(:)))
202 if (ipair <= count_partial)
then
203 max_abs_diff_partial(ipair) = maxval(abs(pot_partial(:, ipair) - pot(:)))
207 call zpoisson_solve(psolver_real_single, namespace, pot_real, rho_batch(:, ipair), all_nodes=.false.)
208 max_abs_diff_real(ipair) = maxval(abs(pot_real_batch(:, ipair) - pot_real(:)))
215 safe_deallocate_a(rho_batch)
216 safe_deallocate_a(pot_batch)
217 safe_deallocate_a(pot_batch_last)
218 safe_deallocate_a(pot_real_batch)
219 safe_deallocate_a(pot_partial)
220 safe_deallocate_a(pot)
221 safe_deallocate_a(pot_real)
222 safe_deallocate_a(diff)
224 write(
message(1),
'(a)')
'Test Poisson FFT batching: Performed a set of single solves'
230 do ipair = 1, batch_size
231 write(
message(1),
'(a,i0,a,es18.10,a,es18.10)')
'Poisson FFT pair ', ipair, &
232 ': mean abs diff = ', mean_diff(ipair),
', max abs diff = ', max_abs_diff(ipair)
235 write(
message(1),
'(a,es18.10)')
'Poisson FFT batch overall mean abs diff = ', sum(mean_diff)/real(batch_size, real64)
236 write(
message(2),
'(a,es18.10)')
'Poisson FFT batch overall max abs diff = ', maxval(max_abs_diff)
239 assert(all(max_abs_diff < tolerance))
241 write(
message(1),
'(a,es18.10)')
'Poisson FFT batch-last (batch_axis=4) overall max abs diff = ', &
242 maxval(max_abs_diff_last)
245 assert(all(max_abs_diff_last < tolerance))
247 write(
message(1),
'(a,i0,a,i0,a,es18.10)')
'Poisson FFT partial batch (count ', count_partial, &
248 ' of capacity ', batch_size,
') overall max abs diff = ', maxval(max_abs_diff_partial)
251 assert(all(max_abs_diff_partial < tolerance))
253 write(
message(1),
'(a,es18.10)')
'Poisson FFT complex-on-real-cube batch overall max abs diff = ', &
254 maxval(max_abs_diff_real)
257 assert(all(max_abs_diff_real < tolerance))
262 safe_deallocate_a(mean_diff)
263 safe_deallocate_a(max_abs_diff)
264 safe_deallocate_a(max_abs_diff_partial)
265 safe_deallocate_a(max_abs_diff_last)
266 safe_deallocate_a(max_abs_diff_real)
269 safe_deallocate_p(sys)
double exp(double __x) __attribute__((__nothrow__
This module handles the calculation mode.
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
integer, parameter, public p_strategy_states
parallelization in states
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
integer, parameter, public fft_batch_unpacked
integer, parameter, public fft_batch_packed
subroutine, public fourier_space_op_end(this)
real(real64), parameter, public m_two
real(real64), parameter, public m_pi
some mathematical constants
complex(real64), parameter, public m_zi
logical pure function, public kpoints_point_is_gamma(this, ik)
This module is intended to contain "only mathematical" functions and procedures.
This module defines the meshes, which are used in Octopus.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
type(mpi_grp_t), public mpi_world
integer, parameter, public poisson_fft
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx, fft_batch_size, fft_batch_axis)
subroutine, public zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
subroutine, public zpoisson_solve_batch(this, pot, rho, kernel, view)
Solves the Poisson equation for batched quantities, using fast Fourier transforms (FFTs).
subroutine, public poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
subroutine, public poisson_end(this)
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine mock_plane_wave_state(mesh, g_vector, state)
Construct a periodic plane-wave factor on the mesh.
subroutine, public test_poisson_fft_batch(namespace)
type(xc_cam_t), parameter, public cam_null
All CAM parameters set to zero.
Class describing the electron system.
Describes mesh distribution to nodes.