Octopus
batch_ops.F90
Go to the documentation of this file.
1!! Copyright (C) 2008 X. Andrade
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
23module batch_ops_oct_m
24 use accel_oct_m
25 use batch_oct_m
26 use blas_oct_m
27 use debug_oct_m
28 use iso_c_binding
29 use global_oct_m
31 use math_oct_m
34 use types_oct_m
35
36 implicit none
37
38 private
39 public :: &
41 batch_axpy, &
43 batch_scal, &
45 batch_xpay, &
63
65 interface batch_axpy
66 module procedure dbatch_axpy_const
67 module procedure zbatch_axpy_const
68 module procedure sbatch_axpy_const
69 module procedure cbatch_axpy_const
70 module procedure dbatch_axpy_vec
71 module procedure zbatch_axpy_vec
72 end interface batch_axpy
73
75 interface batch_scal
76 module procedure dbatch_scal_const
77 module procedure zbatch_scal_const
78 module procedure dbatch_scal_vec
79 module procedure zbatch_scal_vec
80 end interface batch_scal
81
83 interface batch_axpby
84 module procedure dbatch_axpby
85 module procedure zbatch_axpby
86 end interface batch_axpby
87
89 interface batch_scal2v
90 module procedure dbatch_scal2v
91 module procedure zbatch_scal2v
92 end interface batch_scal2v
93
95 interface batch_xpay
96 module procedure dbatch_xpay_vec
97 module procedure zbatch_xpay_vec
98 module procedure dbatch_xpay_const
99 module procedure zbatch_xpay_const
100 end interface batch_xpay
101
102 interface batch_add_with_map
103 module procedure batch_add_with_map_cpu
104 module procedure batch_add_with_map_accel
105 end interface batch_add_with_map
106
107 interface batch_copy_with_map
108 module procedure batch_copy_with_map_cpu
109 module procedure batch_copy_with_map_accel
110 end interface batch_copy_with_map
111
126 interface batch_set_state
127 module procedure dbatch_set_state1
128 module procedure zbatch_set_state1
129 module procedure sbatch_set_state1
130 module procedure cbatch_set_state1
131 module procedure dbatch_set_state2
132 module procedure zbatch_set_state2
133 module procedure sbatch_set_state2
134 module procedure cbatch_set_state2
135 module procedure dbatch_set_state3
136 module procedure zbatch_set_state3
137 module procedure sbatch_set_state3
138 module procedure cbatch_set_state3
139 end interface batch_set_state
140
141 interface batch_get_state
142 module procedure dbatch_get_state1
143 module procedure zbatch_get_state1
144 module procedure sbatch_get_state1
145 module procedure cbatch_get_state1
146 module procedure dbatch_get_state2
147 module procedure zbatch_get_state2
148 module procedure sbatch_get_state2
149 module procedure cbatch_get_state2
150 module procedure dbatch_get_state3
151 module procedure zbatch_get_state3
152 module procedure sbatch_get_state3
153 module procedure cbatch_get_state3
154 end interface batch_get_state
155
156 interface batch_get_points
157 module procedure dbatch_get_points
158 module procedure zbatch_get_points
159 module procedure batch_get_points_accel
160 end interface batch_get_points
161
162 interface batch_set_points
163 module procedure dbatch_set_points
164 module procedure zbatch_set_points
165 module procedure batch_set_points_accel
166 end interface batch_set_points
167
168 interface batch_pointwise_mul
169 module procedure batch_mul_cj
171
174 interface batch_mul_mf
175 module procedure dbatch_mul_mf
176 module procedure zbatch_mul_mf
177 end interface batch_mul_mf
179
180contains
181
182 !--------------------------------------------------------------
184 subroutine batch_set_zero(this, np, async)
185 class(batch_t), intent(inout) :: this
186 integer, optional, intent(in) :: np
188 logical, optional, intent(in) :: async
189
190 integer :: ist_linear, ist, ip, np_
191
192 push_sub(batch_set_zero)
193
194 assert(not_in_openmp())
195
196 call profiling_in("BATCH_SET_ZERO")
198 select case (this%status())
200 np_ = optional_default(np, int(this%pack_size(2), int32))
201 assert(np_ <= int(this%pack_size(2), int32))
202 call accel_set_buffer_to_zero(this%ff_device, this%type(), (int(this%pack_size(1), int32) * np_), async=async)
203
204 case (batch_packed)
205 np_ = optional_default(np, int(this%pack_size(2), int32))
206 assert(np_ <= int(this%pack_size(2), int32))
207 if (this%type() == type_float) then
208 !$omp parallel do private(ist) schedule(static)
209 do ip = 1, np_
210 !$omp simd
211 do ist = 1, int(this%pack_size(1), int32)
212 this%dff_pack(ist, ip) = m_zero
213 end do
214 end do
215 else if (this%type() == type_float_single) then
216 !$omp parallel do private(ist) schedule(static)
217 do ip = 1, np_
218 !$omp simd
219 do ist = 1, int(this%pack_size(1), int32)
220 this%sff_pack(ist, ip) = 0.0_real32
221 end do
222 end do
223 else if (this%type() == type_cmplx_single) then
224 !$omp parallel do private(ist) schedule(static)
225 do ip = 1, np_
226 !$omp simd
227 do ist = 1, int(this%pack_size(1), int32)
228 this%cff_pack(ist, ip) = cmplx(0.0_real32, 0.0_real32, real32)
229 end do
230 end do
231 else
232 !$omp parallel do private(ist) schedule(static)
233 do ip = 1, np_
234 !$omp simd
235 do ist = 1, int(this%pack_size(1), int32)
236 this%zff_pack(ist, ip) = m_z0
237 end do
238 end do
239 end if
240
241 case (batch_not_packed)
242 if (this%type() == type_float) then
243 np_ = optional_default(np, ubound(this%dff_linear, dim=1))
244 assert(np_ <= ubound(this%dff_linear, dim=1))
245 do ist_linear = 1, this%nst_linear
246 !$omp parallel do schedule(static)
247 do ip = 1, np_
248 this%dff_linear(ip, ist_linear) = m_zero
249 end do
250 end do
251 else if (this%type() == type_float_single) then
252 np_ = optional_default(np, ubound(this%sff_linear, dim=1))
253 assert(np_ <= ubound(this%sff_linear, dim=1))
254 do ist_linear = 1, this%nst_linear
255 !$omp parallel do schedule(static)
256 do ip = 1, np_
257 this%sff_linear(ip, ist_linear) = 0.0_real32
258 end do
259 end do
260 else if (this%type() == type_cmplx_single) then
261 np_ = optional_default(np, ubound(this%cff_linear, dim=1))
262 assert(np_ <= ubound(this%cff_linear, dim=1))
263 do ist_linear = 1, this%nst_linear
264 !$omp parallel do schedule(static)
265 do ip = 1, np_
266 this%cff_linear(ip, ist_linear) = cmplx(0.0_real32, 0.0_real32, real32)
267 end do
268 end do
269 else
270 np_ = optional_default(np, ubound(this%zff_linear, dim=1))
271 assert(np_ <= ubound(this%zff_linear, dim=1))
272 do ist_linear = 1, this%nst_linear
273 !$omp parallel do schedule(static)
274 do ip = 1, np_
275 this%zff_linear(ip, ist_linear) = m_z0
276 end do
277 end do
278 end if
280 case default
281 message(1) = "batch_set_zero: unknown batch status."
282 call messages_fatal(1)
283
284 end select
285
286 call profiling_out("BATCH_SET_ZERO")
287
288 pop_sub(batch_set_zero)
289 end subroutine batch_set_zero
290
291 ! --------------------------------------------------------------
293 !
294 subroutine batch_get_points_accel(this, sp, ep, psi, ldpsi1, ldpsi2)
295 class(batch_t), intent(in) :: this
296 integer, intent(in) :: sp
297 integer, intent(in) :: ep
298 type(accel_mem_t), intent(inout) :: psi
299 integer, intent(in) :: ldpsi1
300 integer, intent(in) :: ldpsi2
301
302 integer :: tsize, ii, it
303 type(accel_kernel_t), save :: kernel
304 integer, allocatable :: linear_to_ist(:), linear_to_idim(:)
305 type(accel_mem_t) :: buff_linear_to_ist, buff_linear_to_idim
306
307 push_sub(batch_get_points_accel)
308 call profiling_in("GET_POINTS")
309
310 select case (this%status())
312 call messages_not_implemented('batch_get_points_accel for non-GPU batches')
313
315
316 tsize = types_get_size(this%type())/types_get_size(type_float)
317 safe_allocate(linear_to_ist(1:this%nst_linear*tsize))
318 safe_allocate(linear_to_idim(1:this%nst_linear*tsize))
319 do ii = 1, this%nst_linear
320 do it = 1, tsize
321 linear_to_ist(tsize*(ii-1)+it) = tsize*(this%linear_to_ist(ii) - 1) + it - 1
322 linear_to_idim(tsize*(ii-1)+it) = this%linear_to_idim(ii) - 1
323 end do
324 end do
325
326 call accel_create_buffer(buff_linear_to_ist, accel_mem_read_only, type_integer, this%nst_linear*tsize)
327 call accel_write_buffer(buff_linear_to_ist, this%nst_linear*tsize, linear_to_ist)
328 call accel_create_buffer(buff_linear_to_idim, accel_mem_read_only, type_integer, this%nst_linear*tsize)
329 call accel_write_buffer(buff_linear_to_idim, this%nst_linear*tsize, linear_to_idim)
330
331 call accel_kernel_start_call(kernel, 'points.cu', 'get_points<double>')
332
333 call accel_set_kernel_arg(kernel, 0, sp)
334 call accel_set_kernel_arg(kernel, 1, ep)
335 call accel_set_kernel_arg(kernel, 2, buff_linear_to_ist)
336 call accel_set_kernel_arg(kernel, 3, buff_linear_to_idim)
337 call accel_set_kernel_arg(kernel, 4, this%nst_linear*tsize)
338 call accel_set_kernel_arg(kernel, 5, this%ff_device)
339 call accel_set_kernel_arg(kernel, 6, int(this%pack_size_real(1), int32))
340 call accel_set_kernel_arg(kernel, 7, psi)
341 call accel_set_kernel_arg(kernel, 8, ldpsi1*tsize)
342 call accel_set_kernel_arg(kernel, 9, ldpsi2)
343
344 call accel_kernel_run(kernel, (/1_int64, int(ep - sp + 1, int64)/), (/this%pack_size_real(1), 1_int64/))
345
346 call accel_free_buffer(buff_linear_to_ist)
347 call accel_free_buffer(buff_linear_to_idim)
348 safe_deallocate_a(linear_to_ist)
349 safe_deallocate_a(linear_to_idim)
350
351 end select
352
353 call profiling_out("GET_POINTS")
354
356 end subroutine batch_get_points_accel
357
358 ! --------------------------------------------------------------
360 !
361 subroutine batch_set_points_accel(this, sp, ep, psi, ldpsi1, ldpsi2)
362 class(batch_t), intent(inout) :: this
363 integer, intent(in) :: sp
364 integer, intent(in) :: ep
365 type(accel_mem_t), intent(in) :: psi
366 integer, intent(in) :: ldpsi1
367 integer, intent(in) :: ldpsi2
368
369 integer :: tsize, ii, it
370 type(accel_kernel_t), save :: kernel
371 integer, allocatable :: linear_to_ist(:), linear_to_idim(:)
372 type(accel_mem_t) :: buff_linear_to_ist, buff_linear_to_idim
373
374 push_sub(batch_set_points_accel)
375 call profiling_in("SET_POINTS")
376
377 select case (this%status())
379 call messages_not_implemented('batch_set_points_accel for non-GPU batches')
380
382
383 tsize = types_get_size(this%type())/types_get_size(type_float)
384 safe_allocate(linear_to_ist(1:this%nst_linear*tsize))
385 safe_allocate(linear_to_idim(1:this%nst_linear*tsize))
386 do ii = 1, this%nst_linear
387 do it = 1, tsize
388 linear_to_ist(tsize*(ii-1)+it) = tsize*(this%linear_to_ist(ii) - 1) + it - 1
389 linear_to_idim(tsize*(ii-1)+it) = this%linear_to_idim(ii) - 1
390 end do
391 end do
392
393 call accel_create_buffer(buff_linear_to_ist, accel_mem_read_only, type_integer, this%nst_linear*tsize)
394 call accel_write_buffer(buff_linear_to_ist, this%nst_linear*tsize, linear_to_ist)
395 call accel_create_buffer(buff_linear_to_idim, accel_mem_read_only, type_integer, this%nst_linear*tsize)
396 call accel_write_buffer(buff_linear_to_idim, this%nst_linear*tsize, linear_to_idim)
397
398 call accel_kernel_start_call(kernel, 'points.cu', 'set_points<double>')
399
400 call accel_set_kernel_arg(kernel, 0, sp)
401 call accel_set_kernel_arg(kernel, 1, ep)
402 call accel_set_kernel_arg(kernel, 2, buff_linear_to_ist)
403 call accel_set_kernel_arg(kernel, 3, buff_linear_to_idim)
404 call accel_set_kernel_arg(kernel, 4, this%nst_linear*tsize)
405 call accel_set_kernel_arg(kernel, 5, psi)
406 call accel_set_kernel_arg(kernel, 6, ldpsi1*tsize)
407 call accel_set_kernel_arg(kernel, 7, ldpsi2)
408 call accel_set_kernel_arg(kernel, 8, this%ff_device)
409 call accel_set_kernel_arg(kernel, 9, int(this%pack_size_real(1), int32))
410
411 call accel_kernel_run(kernel, (/1_int64, int(ep - sp + 1, int64)/), (/this%pack_size_real(1), 1_int64/))
412
413 call accel_free_buffer(buff_linear_to_ist)
414 call accel_free_buffer(buff_linear_to_idim)
415 safe_deallocate_a(linear_to_ist)
416 safe_deallocate_a(linear_to_idim)
417
418 end select
419
420 call profiling_out("SET_POINTS")
421
423 end subroutine batch_set_points_accel
424
425 ! -------------------------
429 !
430 integer pure function batch_points_block_size() result(block_size)
431
432 block_size = 61440
433
434 end function batch_points_block_size
435
436! -------------------------
439 subroutine batch_mul_cj(np, xx, yy, zz, conjugate_yy)
440 integer, intent(in) :: np
441 class(batch_t), intent(in) :: xx
442 class(batch_t), intent(in) :: yy
443 class(batch_t), intent(inout) :: zz
444 logical, optional, intent(in) :: conjugate_yy
445
446 integer :: ii, ip
447 logical :: conj_yy
448 integer(int64), dimension(3) :: gsizes, bsizes
449 type(accel_kernel_t), save, target :: kernel_zmul_conj
450 type(accel_kernel_t), save, target :: kernel_zmul
451 type(accel_kernel_t), save, target :: kernel_dmul
452 type(accel_kernel_t), pointer :: kernel
453 push_sub(batch_mul_cj)
454
455 call xx%check_compatibility_with(yy)
456 call xx%check_compatibility_with(zz)
457
458 conj_yy = optional_default(conjugate_yy, .true.)
459
460 select case (xx%status())
461 case (batch_not_packed)
462 if (xx%type() == type_cmplx) then
463 if (conj_yy) then
464 !$omp parallel private(ii, ip)
465 do ii = 1, xx%nst_linear
466 !$omp do schedule(static)
467 do ip = 1, np
468 zz%zff_linear(ip, ii) = xx%zff_linear(ip, ii)*conjg(yy%zff_linear(ip, ii))
469 end do
470 !$omp end do
471 end do
472 !$omp end parallel
473 else
474 !$omp parallel private(ii, ip)
475 do ii = 1, xx%nst_linear
476 !$omp do schedule(static)
477 do ip = 1, np
478 zz%zff_linear(ip, ii) = xx%zff_linear(ip, ii)*yy%zff_linear(ip, ii)
479 end do
480 !$omp end do
481 end do
482 !$omp end parallel
483 end if
484 else
485 !$omp parallel private(ii, ip)
486 do ii = 1, xx%nst_linear
487 !$omp do schedule(static)
488 do ip = 1, np
489 zz%dff_linear(ip, ii) = xx%dff_linear(ip, ii)*yy%dff_linear(ip, ii)
490 end do
491 !$omp end do
492 end do
493 !$omp end parallel
494 end if
495
496 case (batch_packed)
497 if (xx%type() == type_cmplx) then
498 if (conj_yy) then
499 !$omp parallel do private(ii)
500 do ip = 1, np
501 !$omp simd
502 do ii = 1, xx%nst_linear
503 zz%zff_pack(ii, ip) = xx%zff_pack(ii, ip)*conjg(yy%zff_pack(ii, ip))
504 end do
505 end do
506 else
507 !$omp parallel do private(ii)
508 do ip = 1, np
509 !$omp simd
510 do ii = 1, xx%nst_linear
511 zz%zff_pack(ii, ip) = xx%zff_pack(ii, ip)*yy%zff_pack(ii, ip)
512 end do
513 end do
514 end if
515 else
516 !$omp parallel do private(ii)
517 do ip = 1, np
518 !$omp simd
519 do ii = 1, xx%nst_linear
520 zz%dff_pack(ii, ip) = xx%dff_pack(ii, ip)*yy%dff_pack(ii, ip)
521 end do
522 end do
523 end if
524
525 case (batch_device_packed)
526 if (xx%type() == type_cmplx) then
527 if (conj_yy) then
528 kernel => kernel_zmul_conj
529 call accel_kernel_start_call(kernel, 'batch_mul.cu', 'mul_batch<complex<double>, Conjugation::Yes>')
530 else
531 kernel => kernel_zmul
532 call accel_kernel_start_call(kernel, 'batch_mul.cu', 'mul_batch<complex<double>, Conjugation::No>')
533 end if
535 call accel_set_kernel_arg(kernel, 0, np)
536 call accel_set_kernel_arg(kernel, 1, xx%ff_device)
537 call accel_set_kernel_arg(kernel, 2, log2(int(xx%pack_size(1), int32)))
538 call accel_set_kernel_arg(kernel, 3, yy%ff_device)
539 call accel_set_kernel_arg(kernel, 4, log2(int(yy%pack_size(1), int32)))
540 call accel_set_kernel_arg(kernel, 5, zz%ff_device)
541 call accel_set_kernel_arg(kernel, 6, log2(int(zz%pack_size(1), int32)))
542
543 call accel_grid_size_extend_dim(int(np, int64), xx%pack_size(1), gsizes, bsizes, kernel)
544 else
545 kernel => kernel_dmul
546 call accel_kernel_start_call(kernel, 'batch_mul.cu', 'mul_batch<double>')
547
548 call accel_set_kernel_arg(kernel, 0, np)
549 call accel_set_kernel_arg(kernel, 1, xx%ff_device)
550 call accel_set_kernel_arg(kernel, 2, log2(int(xx%pack_size_real(1), int32)))
551 call accel_set_kernel_arg(kernel, 3, yy%ff_device)
552 call accel_set_kernel_arg(kernel, 4, log2(int(yy%pack_size_real(1), int32)))
553 call accel_set_kernel_arg(kernel, 5, zz%ff_device)
554 call accel_set_kernel_arg(kernel, 6, log2(int(zz%pack_size_real(1), int32)))
555
556 call accel_grid_size_extend_dim(int(np, int64), xx%pack_size_real(1), gsizes, bsizes, kernel)
557 end if
558
559 call accel_kernel_run(kernel, gsizes, bsizes)
560 end select
561
562 pop_sub(batch_mul_cj)
563 end subroutine batch_mul_cj
564
565! -------------------------
566 subroutine batch_add_with_map_cpu(np, map, xx, yy, zz)
567 integer, intent(in) :: np
568 integer, intent(in) :: map(:)
569 class(batch_t), intent(in) :: xx
570 class(batch_t), intent(in) :: yy
571 class(batch_t), intent(inout) :: zz
572 type(accel_mem_t) :: buff_map
573
574 push_sub(batch_add_with_map_cpu)
575
576 if (xx%status() /= batch_device_packed) then
577 if (xx%type() == type_float) then
578 call dbatch_add_with_map(np, map, xx, yy, zz)
579 else
580 call zbatch_add_with_map(np, map, xx, yy, zz)
581 end if
582 else
583 ! copy map to GPU if not already there
584 call accel_create_buffer(buff_map, accel_mem_read_only, type_integer, np)
585 call accel_write_buffer(buff_map, np, map)
586 call batch_add_with_map_accel(np, buff_map, xx, yy, zz)
587 call accel_free_buffer(buff_map)
588 end if
589
591 end subroutine batch_add_with_map_cpu
592
593! -------------------------
594 subroutine batch_add_with_map_accel(np, map, xx, yy, zz)
595 integer, intent(in) :: np
596 class(accel_mem_t), intent(in) :: map
597 class(batch_t), intent(in) :: xx
598 class(batch_t), intent(in) :: yy
599 class(batch_t), intent(inout) :: zz
600
601 type(accel_kernel_t), save :: kernel
602 integer(int64), dimension(3) :: gsizes, bsizes
603
605
606 call accel_kernel_start_call(kernel, 'copy.cu', 'add_with_map<double>')
607
608 call accel_set_kernel_arg(kernel, 0, np)
609 call accel_set_kernel_arg(kernel, 1, map)
610 call accel_set_kernel_arg(kernel, 2, xx%ff_device)
611 call accel_set_kernel_arg(kernel, 3, log2(int(xx%pack_size_real(1), int32)))
612 call accel_set_kernel_arg(kernel, 4, yy%ff_device)
613 call accel_set_kernel_arg(kernel, 5, log2(int(yy%pack_size_real(1), int32)))
614 call accel_set_kernel_arg(kernel, 6, zz%ff_device)
615 call accel_set_kernel_arg(kernel, 7, log2(int(zz%pack_size_real(1), int32)))
616
617 ! Compute the grid (extend to another dimensions if the size of the problem is too big)
618 call accel_grid_size_extend_dim(int(np, int64), xx%pack_size_real(1), gsizes, bsizes, kernel)
619
620 call accel_kernel_run(kernel, gsizes, bsizes)
621
623 end subroutine batch_add_with_map_accel
624
625! -------------------------
626 subroutine batch_copy_with_map_cpu(np, map, xx, yy)
627 integer, intent(in) :: np
628 integer, intent(in) :: map(:)
629 class(batch_t), intent(in) :: xx
630 class(batch_t), intent(inout) :: yy
631 type(accel_mem_t) :: buff_map
632
634
635 if (xx%status() /= batch_device_packed) then
636 if (xx%type() == type_float) then
637 call dbatch_copy_with_map(np, map, xx, yy)
638 else
639 call zbatch_copy_with_map(np, map, xx, yy)
640 end if
641 else
642 ! copy map to GPU if not already there
643 call accel_create_buffer(buff_map, accel_mem_read_only, type_integer, np)
644 call accel_write_buffer(buff_map, np, map)
645 call batch_copy_with_map_accel(np, buff_map, xx, yy)
646 call accel_free_buffer(buff_map)
647 end if
648
650 end subroutine batch_copy_with_map_cpu
651
652! -------------------------
653 subroutine batch_copy_with_map_accel(np, map, xx, yy)
654 integer, intent(in) :: np
655 class(accel_mem_t), intent(in) :: map
656 class(batch_t), intent(in) :: xx
657 class(batch_t), intent(inout) :: yy
658
659 type(accel_kernel_t), save :: kernel
660 integer(int64), dimension(3) :: gsizes, bsizes
663
664 call accel_kernel_start_call(kernel, 'copy.cu', 'copy_with_map<double>')
665
666 ! execute only if map has at least one element
667 if (np > 0) then
668 call accel_set_kernel_arg(kernel, 0, np)
669 call accel_set_kernel_arg(kernel, 1, map)
670 call accel_set_kernel_arg(kernel, 2, xx%ff_device)
671 call accel_set_kernel_arg(kernel, 3, log2(int(xx%pack_size_real(1), int32)))
672 call accel_set_kernel_arg(kernel, 4, yy%ff_device)
673 call accel_set_kernel_arg(kernel, 5, log2(int(yy%pack_size_real(1), int32)))
674
675 ! Compute the grid (extend to another dimensions if the size of the problem is too big)
676 call accel_grid_size_extend_dim(int(np, int64), xx%pack_size_real(1), gsizes, bsizes, kernel)
677
678 call accel_kernel_run(kernel, gsizes, bsizes)
679 end if
680
682 end subroutine batch_copy_with_map_accel
683
684 ! -------------------------
688 !
689 subroutine batch_split_complex(np, xx, yy, zz)
690 integer, intent(in) :: np
691 class(batch_t), intent(in) :: xx
692 class(batch_t), intent(inout) :: yy
693 class(batch_t), intent(inout) :: zz
694
695 integer :: ist_linear, ip
696 type(accel_kernel_t), save :: kernel
697 integer(int64), dimension(3) :: gsizes, bsizes
698
699 push_sub(batch_split_complex)
700
701 assert(xx%type() == type_cmplx)
702 assert(yy%type() == type_float)
703 assert(zz%type() == type_float)
704 assert(xx%status() == yy%status())
705 assert(xx%status() == zz%status())
706
707 select case (xx%status())
708 case (batch_not_packed)
709 do ist_linear = 1, xx%nst_linear
710 !$omp parallel do schedule(static)
711 do ip = 1, np
712 yy%dff_linear(ip, ist_linear) = real(xx%zff_linear(ip, ist_linear), real64)
713 zz%dff_linear(ip, ist_linear) = aimag(xx%zff_linear(ip, ist_linear))
714 end do
715 end do
716 case (batch_packed)
717 !$omp parallel do private(ist_linear) schedule(static)
718 do ip = 1, np
719 do ist_linear = 1, xx%nst_linear
720 yy%dff_pack(ist_linear, ip) = real(xx%zff_pack(ist_linear, ip), real64)
721 zz%dff_pack(ist_linear, ip) = aimag(xx%zff_pack(ist_linear, ip))
722 end do
723 end do
724 case (batch_device_packed)
725 call accel_kernel_start_call(kernel, 'split.cu', 'split_complex<double>')
726
727 call accel_set_kernel_arg(kernel, 0, int(xx%pack_size(2), int32))
728 call accel_set_kernel_arg(kernel, 1, xx%ff_device)
729 call accel_set_kernel_arg(kernel, 2, log2(int(xx%pack_size(1), int32)))
730 call accel_set_kernel_arg(kernel, 3, yy%ff_device)
731 call accel_set_kernel_arg(kernel, 4, log2(int(yy%pack_size(1), int32)))
732 call accel_set_kernel_arg(kernel, 5, zz%ff_device)
733 call accel_set_kernel_arg(kernel, 6, log2(int(zz%pack_size(1), int32)))
734
735 ! Compute the grid (extend to another dimensions if the size of the problem is too big)
736 call accel_grid_size_extend_dim(int(np, int64), xx%pack_size(1), gsizes, bsizes, kernel)
737
738 call accel_kernel_run(kernel, gsizes, bsizes)
739 end select
740
741 pop_sub(batch_split_complex)
742 end subroutine batch_split_complex
743
744 ! --------------------------------------------------------------
752 subroutine batch_copy_precision(src, dst, np)
753 class(batch_t), intent(in) :: src
754 class(batch_t), intent(inout) :: dst
755 integer, intent(in) :: np
756
757 integer :: ist, ip
758 integer(int64) :: gsizes(3), bsizes(3)
759 logical :: is_cplx, to_single
760 character(len=47) :: kernel_name
764 type(accel_kernel_t), save, target :: kernels(1:2, 1:2)
765 type(accel_kernel_t), pointer :: kernel
766
767 push_sub(batch_copy_precision)
768
769 assert(src%nst_linear == dst%nst_linear)
770 assert(src%status() == dst%status())
771 assert(type_is_complex(src%type()) .eqv. type_is_complex(dst%type()))
772 assert(type_is_single(src%type()) .neqv. type_is_single(dst%type()))
773
774 is_cplx = type_is_complex(src%type())
775 to_single = type_is_single(dst%type())
776
777 select case (src%status())
778 case (batch_device_packed)
779 if (is_cplx) then
780 kernel_name = merge('precision_copy<complex<double>, complex<float>>', &
781 'precision_copy<complex<float>, complex<double>>', to_single)
782 else
783 kernel_name = merge('precision_copy<double, float>', 'precision_copy<float, double>', to_single)
784 end if
785 kernel => kernels(merge(2, 1, is_cplx), merge(2, 1, to_single))
786 call accel_kernel_start_call(kernel, 'precision_copy.cu', trim(kernel_name))
787 call accel_set_kernel_arg(kernel, 0, np)
788 call accel_set_kernel_arg(kernel, 1, src%nst_linear)
789 call accel_set_kernel_arg(kernel, 2, src%ff_device)
790 call accel_set_kernel_arg(kernel, 3, log2(int(src%pack_size(1), int32)))
791 call accel_set_kernel_arg(kernel, 4, dst%ff_device)
792 call accel_set_kernel_arg(kernel, 5, log2(int(dst%pack_size(1), int32)))
793 call accel_grid_size_extend_dim(int(np, int64), dst%pack_size(1), gsizes, bsizes, kernel)
794 call accel_kernel_run(kernel, gsizes, bsizes)
795 call accel_finish()
796
797 case (batch_packed)
798 if (to_single) then
799 if (is_cplx) then
800 !$omp parallel do private(ist) schedule(static)
801 do ip = 1, np
802 do ist = 1, dst%nst_linear
803 dst%cff_pack(ist, ip) = cmplx(src%zff_pack(ist, ip), kind=real32)
804 end do
805 end do
806 else
807 !$omp parallel do private(ist) schedule(static)
808 do ip = 1, np
809 do ist = 1, dst%nst_linear
810 dst%sff_pack(ist, ip) = real(src%dff_pack(ist, ip), kind=real32)
811 end do
812 end do
813 end if
814 else
815 if (is_cplx) then
816 !$omp parallel do private(ist) schedule(static)
817 do ip = 1, np
818 do ist = 1, dst%nst_linear
819 dst%zff_pack(ist, ip) = src%cff_pack(ist, ip)
820 end do
821 end do
822 else
823 !$omp parallel do private(ist) schedule(static)
824 do ip = 1, np
825 do ist = 1, dst%nst_linear
826 dst%dff_pack(ist, ip) = src%sff_pack(ist, ip)
827 end do
828 end do
829 end if
830 end if
831
832 case (batch_not_packed)
833 if (to_single) then
834 if (is_cplx) then
835 !$omp parallel do private(ip) schedule(static)
836 do ist = 1, dst%nst_linear
837 do ip = 1, np
838 dst%cff_linear(ip, ist) = cmplx(src%zff_linear(ip, ist), kind=real32)
839 end do
840 end do
841 else
842 !$omp parallel do private(ip) schedule(static)
843 do ist = 1, dst%nst_linear
844 do ip = 1, np
845 dst%sff_linear(ip, ist) = real(src%dff_linear(ip, ist), kind=real32)
846 end do
847 end do
848 end if
849 else
850 if (is_cplx) then
851 !$omp parallel do private(ip) schedule(static)
852 do ist = 1, dst%nst_linear
853 do ip = 1, np
854 dst%zff_linear(ip, ist) = src%cff_linear(ip, ist)
855 end do
856 end do
857 else
858 !$omp parallel do private(ip) schedule(static)
859 do ist = 1, dst%nst_linear
860 do ip = 1, np
861 dst%dff_linear(ip, ist) = src%sff_linear(ip, ist)
862 end do
863 end do
864 end if
865 end if
866
867 end select
868
869 pop_sub(batch_copy_precision)
870 end subroutine batch_copy_precision
871
872
873#undef SPECIALIZED
874#include "undef.F90"
875#include "real.F90"
876#include "batch_ops_inc.F90"
877
878#include "undef.F90"
879#include "complex.F90"
880#include "batch_ops_inc.F90"
881
882! Specialized kernels for nst_linear=2
883#define SPECIALIZED 2
884#include "undef.F90"
885#include "real.F90"
886#include "batch_ops_inc.F90"
887
888#include "undef.F90"
889#include "complex.F90"
890#include "batch_ops_inc.F90"
891#undef SPECIALIZED
892
893! Specialized kernels for nst_linear=3
894#define SPECIALIZED 3
895#include "undef.F90"
896#include "real.F90"
897#include "batch_ops_inc.F90"
898
899#include "undef.F90"
900#include "complex.F90"
901#include "batch_ops_inc.F90"
902#undef SPECIALIZED
903
904! Specialized kernels for nst_linear=4
905#define SPECIALIZED 4
906#include "undef.F90"
907#include "real.F90"
908#include "batch_ops_inc.F90"
909
910#include "undef.F90"
911#include "complex.F90"
912#include "batch_ops_inc.F90"
913#undef SPECIALIZED
914
915! Specialized kernels for nst_linear=6
916#define SPECIALIZED 6
917#include "undef.F90"
918#include "real.F90"
919#include "batch_ops_inc.F90"
920
921#include "undef.F90"
922#include "complex.F90"
923#include "batch_ops_inc.F90"
924#undef SPECIALIZED
925
926! Specialized kernels for nst_linear=8
927#define SPECIALIZED 8
928#include "undef.F90"
929#include "real.F90"
930#include "batch_ops_inc.F90"
931
932#include "undef.F90"
933#include "complex.F90"
934#include "batch_ops_inc.F90"
935#undef SPECIALIZED
936
937! Single-precision batch operations: batch_ops_inc.F90 skips everything that needs a
938! single-precision lalg wrapper and keeps the subset the exchange path uses.
939#include "undef.F90"
940#include "real32.F90"
941#include "batch_ops_inc.F90"
942
943#include "undef.F90"
944#include "complex32.F90"
945#include "batch_ops_inc.F90"
946
947end module batch_ops_oct_m
948
949!! Local Variables:
950!! mode: f90
951!! coding: utf-8
952!! End:
batchified version of the BLAS axpy routine:
Definition: batch_ops.F90:160
batchified multiplication by mesh function with optional conjugation:
Definition: batch_ops.F90:269
batchified scale with optional conjugation:
Definition: batch_ops.F90:184
scale a batch by a constant or vector
Definition: batch_ops.F90:170
There are several ways how to call batch_set_state and batch_get_state:
Definition: batch_ops.F90:221
batchified version of
Definition: batch_ops.F90:190
double log2(double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:990
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
Definition: accel.F90:1864
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
This module implements batches of mesh functions.
Definition: batch.F90:135
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
Definition: batch.F90:311
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
Definition: batch.F90:311
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
Definition: batch.F90:311
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
subroutine zbatch_get_state3(this, ii, np, psi, async)
Definition: batch_ops.F90:3387
subroutine dbatch_get_state3(this, ii, np, psi, async)
Definition: batch_ops.F90:1428
subroutine batch_copy_with_map_accel(np, map, xx, yy)
Definition: batch_ops.F90:749
subroutine zbatch_get_state1(this, ist, np, psi, async)
Write a get of state with np points from a batch.
Definition: batch_ops.F90:3242
subroutine, public zbatch_copy_with_map_to_array(np, map, xx, array)
Transfer a batch from the mesh to an array on the submesh (defined by a map)
Definition: batch_ops.F90:4633
subroutine, public dbatch_ax_function_py(np, aa, psi, yy)
This routine performs a set of axpy operations adding the same function psi to all functions of a bat...
Definition: batch_ops.F90:1713
subroutine dbatch_set_state1(this, ist, np, psi)
Write a single state with np points into a batch at position ist.
Definition: batch_ops.F90:1146
subroutine dbatch_axpy_const(np, aa, xx, yy)
This routine applies a 'pair-wise' axpy operation to all functions of the batches xx and yy,...
Definition: batch_ops.F90:1050
subroutine zbatch_axpby(np, aa, xx, bb, yy)
calculate yy(ist,:) = aa*xx(ist,:) + bb*yy(ist,:) for a batch
Definition: batch_ops.F90:4050
subroutine cbatch_axpy_const(np, aa, xx, yy)
This routine applies a 'pair-wise' axpy operation to all functions of the batches xx and yy,...
Definition: batch_ops.F90:8759
subroutine zbatch_get_points(this, sp, ep, psi)
copy a set of points into a mesh function
Definition: batch_ops.F90:4382
subroutine dbatch_xpay_vec(np, xx, aa, yy, a_start, a_full)
calculate yy(ist,:) = xx(ist,:) + aa(ist)*yy(ist,:) for a batch
Definition: batch_ops.F90:1976
subroutine dbatch_scal_vec(np, aa, xx, a_start, a_full)
Definition: batch_ops.F90:2901
subroutine dbatch_set_state2(this, index, np, psi)
Write a single state with np points into a batch at position defined by index.
Definition: batch_ops.F90:1258
subroutine dbatch_copy_with_map(np, map, xx, yy)
Definition: batch_ops.F90:2788
subroutine cbatch_get_state2(this, index, np, psi, async)
Definition: batch_ops.F90:9123
subroutine, public dbatch_copy_with_map_to_array(np, map, xx, array)
Transfer a batch from the mesh to an array on the submesh (defined by a map)
Definition: batch_ops.F90:2831
subroutine dbatch_scal2v(np, aa, xx, yy, conjugate_xx)
calculate yy(ist,:) = aa*CJ(xx(ist,:)) for a batch
Definition: batch_ops.F90:2273
subroutine dbatch_get_state2(this, index, np, psi, async)
Definition: batch_ops.F90:1410
subroutine dbatch_axpy_vec(np, aa, xx, yy, a_start, a_full)
A simple switch between specialized kernels and generic kernels.
Definition: batch_ops.F90:2877
subroutine dbatch_set_state3(this, ii, np, psi)
Write a set of state with np points into a batch.
Definition: batch_ops.F90:1276
subroutine zbatch_axpy_const(np, aa, xx, yy)
This routine applies a 'pair-wise' axpy operation to all functions of the batches xx and yy,...
Definition: batch_ops.F90:3012
subroutine sbatch_set_state3(this, ii, np, psi)
Write a set of state with np points into a batch.
Definition: batch_ops.F90:8495
subroutine zbatch_scal_const(np, aa, xx)
scale all functions in a batch by constant aa
Definition: batch_ops.F90:3745
subroutine zbatch_get_state2(this, index, np, psi, async)
Definition: batch_ops.F90:3369
subroutine zbatch_xpay_const(np, xx, aa, yy)
calculate yy(ist) = xx(ist) + aa*yy(ist) for a batch
Definition: batch_ops.F90:4019
subroutine, public batch_split_complex(np, xx, yy, zz)
extract the real and imaginary parts of a complex batch
Definition: batch_ops.F90:785
subroutine batch_add_with_map_accel(np, map, xx, yy, zz)
Definition: batch_ops.F90:690
subroutine dbatch_set_points(this, sp, ep, psi)
copy a set of points into a mesh function
Definition: batch_ops.F90:2661
subroutine dbatch_get_state1(this, ist, np, psi, async)
Write a get of state with np points from a batch.
Definition: batch_ops.F90:1296
subroutine zbatch_copy_with_map(np, map, xx, yy)
Definition: batch_ops.F90:4590
subroutine dbatch_mul_mf(np, ff, xx, yy, conjugate_xx)
calculate yy(ist,:) = ff(:) * CJ(xx(ist,:)) for a batch
Definition: batch_ops.F90:2422
subroutine, public batch_set_zero(this, np, async)
fill all mesh functions of the batch with zero
Definition: batch_ops.F90:280
subroutine, public zbatch_ax_function_py(np, aa, psi, yy)
This routine performs a set of axpy operations adding the same function psi to all functions of a bat...
Definition: batch_ops.F90:3655
subroutine zbatch_axpy_vec(np, aa, xx, yy, a_start, a_full)
A simple switch between specialized kernels and generic kernels.
Definition: batch_ops.F90:4679
subroutine cbatch_set_state1(this, ist, np, psi)
Write a single state with np points into a batch at position ist.
Definition: batch_ops.F90:8850
subroutine batch_set_points_accel(this, sp, ep, psi, ldpsi1, ldpsi2)
GPU version of batch_set_points.
Definition: batch_ops.F90:457
subroutine dbatch_xpay_const(np, xx, aa, yy)
calculate yy(ist) = xx(ist) + aa*yy(ist) for a batch
Definition: batch_ops.F90:2119
subroutine dbatch_axpby(np, aa, xx, bb, yy)
calculate yy(ist,:) = aa*xx(ist,:) + bb*yy(ist,:) for a batch
Definition: batch_ops.F90:2150
subroutine dbatch_get_points(this, sp, ep, psi)
copy a set of points into a mesh function
Definition: batch_ops.F90:2581
subroutine zbatch_scal2v(np, aa, xx, yy, conjugate_xx)
calculate yy(ist,:) = aa*CJ(xx(ist,:)) for a batch
Definition: batch_ops.F90:4140
integer pure function, public batch_points_block_size()
determine the device block size
Definition: batch_ops.F90:526
subroutine dbatch_add_with_map(np, map, xx, yy, zz)
Definition: batch_ops.F90:2746
subroutine zbatch_mul_mf(np, ff, xx, yy, conjugate_xx)
calculate yy(ist,:) = ff(:) * CJ(xx(ist,:)) for a batch
Definition: batch_ops.F90:4257
subroutine sbatch_get_state1(this, ist, np, psi, async)
Write a get of state with np points from a batch.
Definition: batch_ops.F90:8515
subroutine sbatch_get_state2(this, index, np, psi, async)
Definition: batch_ops.F90:8629
subroutine zbatch_xpay_vec(np, xx, aa, yy, a_start, a_full)
calculate yy(ist,:) = xx(ist,:) + aa(ist)*yy(ist,:) for a batch
Definition: batch_ops.F90:3901
subroutine sbatch_set_state1(this, ist, np, psi)
Write a single state with np points into a batch at position ist.
Definition: batch_ops.F90:8356
subroutine, public batch_copy_precision(src, dst, np)
Copy the data of a batch to another batch of the same logical shape but the opposite precision (doubl...
Definition: batch_ops.F90:848
subroutine cbatch_get_state3(this, ii, np, psi, async)
Definition: batch_ops.F90:9141
subroutine batch_mul_cj(np, xx, yy, zz, conjugate_yy)
Point-wise multiply two batches with optional conjugation on yy: zz_i = xx_i * CJ(yy_i)
Definition: batch_ops.F90:535
subroutine sbatch_get_state3(this, ii, np, psi, async)
Definition: batch_ops.F90:8647
subroutine sbatch_set_state2(this, index, np, psi)
Write a single state with np points into a batch at position defined by index.
Definition: batch_ops.F90:8477
subroutine zbatch_set_state1(this, ist, np, psi)
Write a single state with np points into a batch at position ist.
Definition: batch_ops.F90:3096
subroutine batch_add_with_map_cpu(np, map, xx, yy, zz)
Definition: batch_ops.F90:662
subroutine zbatch_scal_vec(np, aa, xx, a_start, a_full)
Definition: batch_ops.F90:4703
subroutine cbatch_set_state3(this, ii, np, psi)
Write a set of state with np points into a batch.
Definition: batch_ops.F90:8976
subroutine zbatch_set_state2(this, index, np, psi)
Write a single state with np points into a batch at position defined by index.
Definition: batch_ops.F90:3204
subroutine sbatch_axpy_const(np, aa, xx, yy)
This routine applies a 'pair-wise' axpy operation to all functions of the batches xx and yy,...
Definition: batch_ops.F90:8245
subroutine, public zbatch_axpy_function(np, aa, xx, psi, nst)
This routine performs a set of axpy operations for each function x of a batch (xx),...
Definition: batch_ops.F90:3545
subroutine zbatch_set_points(this, sp, ep, psi)
copy a set of points into a mesh function
Definition: batch_ops.F90:4474
subroutine zbatch_add_with_map(np, map, xx, yy, zz)
Definition: batch_ops.F90:4548
subroutine, public dbatch_axpy_function(np, aa, xx, psi, nst)
This routine performs a set of axpy operations for each function x of a batch (xx),...
Definition: batch_ops.F90:1603
subroutine batch_get_points_accel(this, sp, ep, psi, ldpsi1, ldpsi2)
GPU version of batch_get_points.
Definition: batch_ops.F90:390
subroutine cbatch_set_state2(this, index, np, psi)
Write a single state with np points into a batch at position defined by index.
Definition: batch_ops.F90:8958
subroutine zbatch_set_state3(this, ii, np, psi)
Write a set of state with np points into a batch.
Definition: batch_ops.F90:3222
subroutine cbatch_get_state1(this, ist, np, psi, async)
Write a get of state with np points from a batch.
Definition: batch_ops.F90:8996
subroutine batch_copy_with_map_cpu(np, map, xx, yy)
Definition: batch_ops.F90:722
subroutine dbatch_scal_const(np, aa, xx)
scale all functions in a batch by constant aa
Definition: batch_ops.F90:1803
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:120
real(real64), parameter, public m_zero
Definition: global.F90:200
logical pure function, public not_in_openmp()
Definition: global.F90:567
complex(real64), parameter, public m_z0
Definition: global.F90:210
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
type(type_t), parameter, public type_cmplx_single
Definition: types.F90:142
type(type_t), parameter, public type_float_single
Definition: types.F90:141
integer pure function, public types_get_size(this)
Definition: types.F90:157
type(type_t), parameter, public type_integer
Definition: types.F90:138
type(type_t), parameter, public type_float
Definition: types.F90:136
Class defining batches of mesh functions.
Definition: batch.F90:164
int true(void)