Octopus
accel.F90
Go to the documentation of this file.
1!! Copyright (C) 2010-2016 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
21#if defined(HAVE_CUDA)
22#define HAVE_ACCEL 1
23#endif
24
25module accel_oct_m
27 use cuda_oct_m
28 use debug_oct_m
29 use global_oct_m
30 use iso_c_binding, only: c_null_ptr, c_size_t
31 use, intrinsic :: iso_fortran_env
32 use loct_oct_m
33 use math_oct_m
35 use mpi_oct_m
37 use types_oct_m
38 use parser_oct_m
42 use string_oct_m
43
44 implicit none
45
46 private
47
48 public :: &
53 accel_t, &
56 accel_init, &
57 accel_end, &
89
90 integer, public, parameter :: &
91 ACCEL_MEM_READ_ONLY = 0, &
94
96 ! Components are public by default
97#if defined(HAVE_CUDA)
98 type(c_ptr) :: cuda_context
99#else
100 integer :: dummy
101#endif
102 end type accel_context_t
103
104 type accel_device_t
105 ! Components are public by default
106#if defined(HAVE_CUDA)
107 type(c_ptr) :: cuda_device
108#else
109 integer :: dummy
110#endif
111 end type accel_device_t
112
113 type accel_t
114 ! Components are public by default
115 type(accel_context_t) :: context
116 type(accel_device_t) :: device
117 type(c_ptr) :: cuda_stream
118 type(c_ptr) :: program_map
119 integer :: max_block_size
120 integer(int64) :: shared_memory_size
121 integer(int64) :: global_memory_size
122 logical :: enabled
123 logical :: allow_CPU_only
124 logical :: cuda_mpi
125 integer :: warp_size
126 integer(int64) :: initialize_buffers
127 character(len=32) :: debug_flag
128 integer(int64) :: max_block_dim(3)
129 integer(int64) :: max_grid_dim(3)
130 end type accel_t
131
132 type accel_mem_t
133 ! Components are public by default
134 type(c_ptr) :: mem
135 integer(c_size_t) :: size = 0
136 type(type_t) :: type
137 integer :: flags = 0
138 logical :: allocated = .false.
139 end type accel_mem_t
140
141 type accel_kernel_t
142 ! Components are public by default
143#ifdef HAVE_CUDA
144 type(c_ptr) :: cuda_kernel
145 type(c_ptr) :: arguments
146#endif
147 logical :: initialized = .false.
148 type(accel_kernel_t), pointer :: next
149 integer :: arg_count
150 character(len=128) :: kernel_name
151 end type accel_kernel_t
152
153 type(accel_t), public :: accel
154
155 ! the kernels
156 type(accel_kernel_t), public, target, save :: kernel_vpsi
157 type(accel_kernel_t), public, target, save :: kernel_vpsi_complex
158 type(accel_kernel_t), public, target, save :: kernel_vpsi_spinors
159 type(accel_kernel_t), public, target, save :: kernel_vpsi_spinors_complex
160 type(accel_kernel_t), public, target, save :: kernel_daxpy
161 type(accel_kernel_t), public, target, save :: kernel_zaxpy
162 type(accel_kernel_t), public, target, save :: kernel_saxpy
163 type(accel_kernel_t), public, target, save :: kernel_caxpy
164 type(accel_kernel_t), public, target, save :: kernel_copy
165 type(accel_kernel_t), public, target, save :: kernel_scopy
166 type(accel_kernel_t), public, target, save :: kernel_copy_complex_to_real
167 type(accel_kernel_t), public, target, save :: kernel_copy_real_to_complex
168 type(accel_kernel_t), public, target, save :: dpack
169 type(accel_kernel_t), public, target, save :: zpack
170 type(accel_kernel_t), public, target, save :: spack
171 type(accel_kernel_t), public, target, save :: cpack
172 type(accel_kernel_t), public, target, save :: dunpack
173 type(accel_kernel_t), public, target, save :: zunpack
174 type(accel_kernel_t), public, target, save :: sunpack
175 type(accel_kernel_t), public, target, save :: cunpack
176 type(accel_kernel_t), public, target, save :: kernel_ghost_reorder
177 type(accel_kernel_t), public, target, save :: kernel_density_real
178 type(accel_kernel_t), public, target, save :: kernel_density_complex
179 type(accel_kernel_t), public, target, save :: kernel_density_spinors
180 type(accel_kernel_t), public, target, save :: kernel_phase
181 type(accel_kernel_t), public, target, save :: kernel_phase_spiral
182 type(accel_kernel_t), public, target, save :: zkernel_dot_matrix_spinors
183 type(accel_kernel_t), public, target, save :: dzmul_batch
184 type(accel_kernel_t), public, target, save :: zzmul_batch
186 interface accel_grid_size
188 end interface accel_grid_size
189
192 end interface accel_grid_size_extend_dim
193
194 interface accel_padded_size
196 end interface accel_padded_size
197
198 interface accel_create_buffer
200 end interface accel_create_buffer
201
205
206 interface accel_kernel_run
207 module procedure accel_kernel_run_4, accel_kernel_run_8
208 end interface accel_kernel_run
209
249 end interface accel_write_buffer
250
277 end interface accel_read_buffer
280 module procedure &
288 end interface accel_set_kernel_arg
310
311 integer :: buffer_alloc_count
312 integer(int64) :: allocated_mem
313 type(accel_kernel_t), pointer :: head
314 type(alloc_cache_t) :: memcache
315
316contains
317
318 pure logical function accel_is_enabled() result(enabled)
319#ifdef HAVE_ACCEL
320 enabled = accel%enabled
321#else
322 enabled = .false.
323#endif
324 end function accel_is_enabled
325
326 ! ------------------------------------------
327
328 pure logical function accel_allow_cpu_only() result(allow)
329#ifdef HAVE_ACCEL
330 allow = accel%allow_CPU_only
331#else
332 allow = .true.
333#endif
334 end function accel_allow_cpu_only
335
336 ! ------------------------------------------
337
338 subroutine accel_init(base_grp, namespace)
339 type(mpi_grp_t), intent(inout) :: base_grp
340 type(namespace_t), intent(in) :: namespace
341
342 logical :: disable, default, run_benchmark
343 integer :: idevice
344#ifdef HAVE_CUDA
345 integer :: dim
346#ifdef HAVE_MPI
347 character(len=256) :: sys_name
348#endif
349#endif
350
351 push_sub(accel_init)
352
353 buffer_alloc_count = 0
354
355 !%Variable DisableAccel
356 !%Type logical
357 !%Default yes
358 !%Section Execution::Accel
359 !%Description
360 !% If Octopus was compiled with CUDA support, it will
361 !% try to initialize and use an accelerator device. By setting this
362 !% variable to <tt>yes</tt> you force Octopus not to use an accelerator even it is available.
363 !%End
364 call messages_obsolete_variable(namespace, 'DisableOpenCL', 'DisableAccel')
365#ifdef HAVE_ACCEL
366 default = .false.
367#else
368 default = .true.
369#endif
370 call parse_variable(namespace, 'DisableAccel', default, disable)
371 accel%enabled = .not. disable
372
373#ifndef HAVE_ACCEL
374 if (accel%enabled) then
375 message(1) = 'Octopus was compiled without Cuda support.'
376 call messages_fatal(1)
377 end if
378#endif
379
380 if (.not. accel_is_enabled()) then
381 pop_sub(accel_init)
382 return
383 end if
384
385 call messages_obsolete_variable(namespace, 'AccelPlatform')
386 call messages_obsolete_variable(namespace, 'OpenCLPlatform', 'AccelPlatform')
387
388 !%Variable AccelDevice
389 !%Type integer
390 !%Default 0
391 !%Section Execution::Accel
392 !%Description
393 !% This variable selects the GPU that Octopus will use. You can specify a
394 !% numerical id to select a specific device.
395 !%
396 !% In case of MPI enabled runs devices are distributed in a round robin fashion,
397 !% starting at this value.
398 !%End
399 call parse_variable(namespace, 'AccelDevice', 0, idevice)
400
401 call messages_obsolete_variable(namespace, 'OpenCLDevice', 'AccelDevice')
402
403 if (idevice < 0) then
404 call messages_write('Invalid AccelDevice')
405 call messages_fatal()
406 end if
408 call messages_print_with_emphasis(msg="GPU acceleration", namespace=namespace)
410#ifdef HAVE_CUDA
411 if (idevice<0) idevice = 0
412 call cuda_init(accel%context%cuda_context, accel%device%cuda_device, accel%cuda_stream, &
413 idevice, base_grp%rank)
414#ifdef HAVE_MPI
415 call loct_sysname(sys_name)
416 write(message(1), '(A,I5,A,I5,2A)') "Rank ", base_grp%rank, " uses device number ", idevice, &
417 " on ", trim(sys_name)
418 call messages_info(1, all_nodes = .true.)
419#endif
420
421 call cublas_init(accel%cuda_stream)
422#endif
424
425 ! Get some device information that we will need later
426#ifdef HAVE_CUDA
427 call cuda_device_total_memory(accel%device%cuda_device, accel%global_memory_size)
428 call cuda_device_shared_memory(accel%device%cuda_device, accel%shared_memory_size)
429 call cuda_device_max_threads_per_block(accel%device%cuda_device, accel%max_block_size)
430 call cuda_device_get_warpsize(accel%device%cuda_device, accel%warp_size)
431 call cuda_device_max_block_dim_x(accel%device%cuda_device, dim)
432 accel%max_block_dim(1) = int(dim, int64)
433 call cuda_device_max_block_dim_y(accel%device%cuda_device, dim)
434 accel%max_block_dim(2) = int(dim, int64)
435 call cuda_device_max_block_dim_z(accel%device%cuda_device, dim)
436 accel%max_block_dim(3) = int(dim, int64)
437 call cuda_device_max_grid_dim_x(accel%device%cuda_device, dim)
438 accel%max_grid_dim(1) = int(dim, int64)
439 call cuda_device_max_grid_dim_y(accel%device%cuda_device, dim)
440 accel%max_grid_dim(2) = int(dim, int64)
441 call cuda_device_max_grid_dim_z(accel%device%cuda_device, dim)
442 accel%max_grid_dim(3) = int(dim, int64)
443#endif
444
445 if (base_grp%is_root()) call device_info()
446
447 ! initialize the cache used to speed up allocations
448 call alloc_cache_init(memcache, nint(0.25_real64*accel%global_memory_size, int64))
449
450 ! now initialize the kernels
452
453#if defined(HAVE_HIP)
454 accel%debug_flag = "-g"
455#elif defined(HAVE_CUDA)
456 accel%debug_flag = "-lineinfo"
457#endif
458
459 call accel_kernel_start_call(kernel_vpsi, 'vpsi.cu', "vpsi<double>")
460 call accel_kernel_start_call(kernel_vpsi_complex, 'vpsi.cu', "vpsi_complex<double>")
461 call accel_kernel_start_call(kernel_vpsi_spinors, 'vpsi.cu', "vpsi_spinors<double>")
462 call accel_kernel_start_call(kernel_vpsi_spinors_complex, 'vpsi.cu', "vpsi_spinors_complex<double>")
463 call accel_kernel_start_call(kernel_daxpy, 'axpy.cu', "axpy<double>")
464 call accel_kernel_start_call(kernel_zaxpy, 'axpy.cu', "axpy<complex<double>>")
465 call accel_kernel_start_call(kernel_saxpy, 'axpy.cu', "axpy<float>")
466 call accel_kernel_start_call(kernel_caxpy, 'axpy.cu', "axpy<complex<float>>")
467 call accel_kernel_start_call(dpack, 'pack.cu', "pack<double>")
468 call accel_kernel_start_call(zpack, 'pack.cu', "pack<complex<double>>")
469 call accel_kernel_start_call(spack, 'pack.cu', "pack<float>")
470 call accel_kernel_start_call(cpack, 'pack.cu', "pack<complex<float>>")
471 call accel_kernel_start_call(dunpack, 'pack.cu', "unpack<double>")
472 call accel_kernel_start_call(zunpack, 'pack.cu', "unpack<complex<double>>")
473 call accel_kernel_start_call(sunpack, 'pack.cu', "unpack<float>")
474 call accel_kernel_start_call(cunpack, 'pack.cu', "unpack<complex<float>>")
475 call accel_kernel_start_call(kernel_copy, 'copy.cu', "copy<double>")
476 call accel_kernel_start_call(kernel_scopy, 'copy.cu', "copy<float>")
477 call accel_kernel_start_call(kernel_copy_complex_to_real, 'copy.cu', "copy_complex_to_real<double>")
478 call accel_kernel_start_call(kernel_copy_real_to_complex, 'copy.cu', "copy_real_to_complex<double>")
479 call accel_kernel_start_call(kernel_ghost_reorder, 'ghost.cu', "ghost_reorder<double>")
480 call accel_kernel_start_call(kernel_density_real, 'density.cu', "density<double, double>")
481 call accel_kernel_start_call(kernel_density_complex, 'density.cu', "density<double, complex<double>>")
482 call accel_kernel_start_call(kernel_density_spinors, 'density.cu', "density_spinors<double>")
483 call accel_kernel_start_call(kernel_phase, 'phase.cu', "phase<double>")
484 call accel_kernel_start_call(zkernel_dot_matrix_spinors, 'mesh_batch.cu', "zdot_matrix_spinors<double>")
485
486
487 call accel_kernel_start_call(dzmul_batch, 'mul.cu', 'zmul_batch<double, double>')
488 call accel_kernel_start_call(zzmul_batch, 'mul.cu', 'zmul_batch<double, complex<double>>')
489
490
491 !%Variable AccelBenchmark
492 !%Type logical
493 !%Default no
494 !%Section Execution::Accel
495 !%Description
496 !% If this variable is set to yes, Octopus will run some
497 !% routines to benchmark the performance of the accelerator device.
498 !%End
499 call parse_variable(namespace, 'AccelBenchmark', .false., run_benchmark)
500
501 call messages_obsolete_variable(namespace, 'OpenCLBenchmark', 'AccelBenchmark')
502
503 if (run_benchmark) then
505 end if
506
507 !%Variable GPUAwareMPI
508 !%Type logical
509 !%Section Execution::Accel
510 !%Description
511 !% If Octopus was compiled with GPU support and MPI support and if the MPI
512 !% implementation is GPU-aware (i.e., it supports communication using device pointers),
513 !% this switch can be set to true to use the GPU-aware MPI features. The advantage
514 !% of this approach is that it can do, e.g., peer-to-peer copies between devices without
515 !% going through the host memory.
516 !% The default is false, except when the configure switch --enable-cudampi is set, in which
517 !% case this variable is set to true.
518 !%End
519#ifdef HAVE_CUDA_MPI
520 default = .true.
521#else
522 default = .false.
523#endif
524 call parse_variable(namespace, 'GPUAwareMPI', default, accel%cuda_mpi)
525 if (accel%cuda_mpi) then
526#ifndef HAVE_CUDA_MPI
527 call messages_write("Warning: trying to use GPU-aware MPI, but we have not detected support in the linked MPI library.")
528 call messages_warning()
529#endif
530 call messages_write("Using GPU-aware MPI.")
531 call messages_info()
532 end if
533
534
535 !%Variable AllowCPUonly
536 !%Type logical
537 !%Section Execution::Accel
538 !%Description
539 !% In order to prevent waste of resources, the code will normally stop when the GPU is disabled due to
540 !% incomplete implementations or incompatibilities. AllowCPUonly = yes overrides this and allows the
541 !% code execution also in these cases.
542 !%End
543#if defined (HAVE_ACCEL)
544 default = .false.
545#else
546 default = .true.
547#endif
548 call parse_variable(namespace, 'AllowCPUonly', default, accel%allow_CPU_only)
549
550
551 !%Variable InitializeGPUBuffers
552 !%Type integer
553 !%Default no
554 !%Section Execution::Accel
555 !%Description
556 !% Initialize new GPU buffers to zero on creation (use only for debugging, as it has a performance impact!).
557 !%Option no 0
558 !% Do not initialize GPU buffers.
559 !%Option yes 1
560 !% Initialize GPU buffers to zero.
561 !%Option nan 2
562 !% Initialize GPU buffers to nan.
563 !%End
564 call parse_variable(namespace, 'InitializeGPUBuffers', option__initializegpubuffers__no, accel%initialize_buffers)
565 if (.not. varinfo_valid_option('InitializeGPUBuffers', accel%initialize_buffers)) then
566 call messages_input_error(namespace, 'InitializeGPUBuffers')
567 end if
568
569
570 call messages_print_with_emphasis(namespace=namespace)
571
572 pop_sub(accel_init)
573
574 contains
575
576 subroutine device_info()
577#ifdef HAVE_CUDA
578 integer :: version
579 character(kind=c_char) :: cval_str(257)
580#endif
581 integer :: major, minor
582 character(len=256) :: val_str
583
584 push_sub(accel_init.device_info)
585
586 call messages_new_line()
587 call messages_write('Selected device:')
588 call messages_new_line()
589
590#ifdef HAVE_CUDA
591#ifdef __HIP_PLATFORM_AMD__
592 call messages_write(' Framework : ROCm')
593#else
594 call messages_write(' Framework : CUDA')
595#endif
596#endif
597 call messages_info()
598
599#ifdef HAVE_CUDA
600 call messages_write(' Device type : GPU', new_line = .true.)
601#ifdef __HIP_PLATFORM_AMD__
602 call messages_write(' Device vendor : AMD Corporation', new_line = .true.)
603#else
604 call messages_write(' Device vendor : NVIDIA Corporation', new_line = .true.)
605#endif
606#endif
607
608#ifdef HAVE_CUDA
609 cval_str = c_null_char
610 call cuda_device_name(accel%device%cuda_device, cval_str)
611 call string_c_to_f(cval_str, val_str)
612#endif
613 call messages_write(' Device name : '//trim(val_str))
614 call messages_new_line()
615
616#ifdef HAVE_CUDA
617 call cuda_device_capability(accel%device%cuda_device, major, minor)
618#endif
619 call messages_write(' Cuda capabilities :')
620 call messages_write(major, fmt = '(i2)')
621 call messages_write('.')
622 call messages_write(minor, fmt = '(i1)')
623 call messages_new_line()
624
625 ! VERSION
626#ifdef HAVE_CUDA
627 call cuda_driver_version(version)
628 call messages_write(' Driver version : ')
629 call messages_write(version)
630#endif
631 call messages_new_line()
632
633
634 call messages_write(' Device memory :')
635 call messages_write(accel%global_memory_size, units=unit_megabytes)
636 call messages_new_line()
637
638 call messages_write(' Shared memory :')
639 call messages_write(accel%shared_memory_size, units=unit_kilobytes)
640 call messages_new_line()
641
642 call messages_write(' Max. block size :')
643 call messages_write(accel%max_block_size)
644 call messages_new_line()
645
646 call messages_info()
647
648 pop_sub(accel_init.device_info)
649 end subroutine device_info
650
651 end subroutine accel_init
652
653 ! ------------------------------------------
654 subroutine accel_end(namespace)
655 type(namespace_t), intent(in) :: namespace
656
657 integer(int64) :: hits, misses
658 real(real64) :: volume_hits, volume_misses
659 logical :: found
660 type(accel_mem_t) :: tmp
661
662 push_sub(accel_end)
663
664 if (accel_is_enabled()) then
665
666 ! Release global buffers
667
668 do
669 call alloc_cache_get(memcache, alloc_cache_any_size, found, tmp%mem)
670 if (.not. found) exit
671
672#ifdef HAVE_CUDA
673 call cuda_mem_free(tmp%mem)
674#endif
675 end do
676
677 call alloc_cache_end(memcache, hits, misses, volume_hits, volume_misses)
678
679 call messages_print_with_emphasis(msg="Acceleration-device allocation cache", namespace=namespace)
680
681 call messages_new_line()
682 call messages_write(' Number of allocations =')
683 call messages_write(hits + misses, new_line = .true.)
684 call messages_write(' Volume of allocations =')
685 call messages_write(volume_hits + volume_misses, fmt = 'f18.1', units = unit_gigabytes, align_left = .true., &
686 new_line = .true.)
687 call messages_write(' Hit ratio =')
688 if (hits + misses > 0) then
689 call messages_write(hits/real(hits + misses, real64)*100, fmt='(f6.1)', align_left = .true.)
690 else
691 call messages_write(m_zero, fmt='(f6.1)', align_left = .true.)
692 end if
693 call messages_write('%', new_line = .true.)
694 call messages_write(' Volume hit ratio =')
695 if (volume_hits + volume_misses > 0) then
696 call messages_write(volume_hits/(volume_hits + volume_misses)*100, fmt='(f6.1)', align_left = .true.)
697 else
698 call messages_write(m_zero, fmt='(f6.1)', align_left = .true.)
699 end if
700 call messages_write('%')
701 call messages_new_line()
702 call messages_info()
703
704 call messages_print_with_emphasis(namespace=namespace)
705 end if
706
708
709 if (accel_is_enabled()) then
710#ifdef HAVE_CUDA
711 call cublas_end()
712 if (.not. accel%cuda_mpi) then ! CUDA aware MPI finalize will do the cleanup
713 call cuda_end(accel%context%cuda_context, accel%device%cuda_device)
714 end if
715#endif
716
717 if (buffer_alloc_count /= 0) then
718 call messages_write('Accel:')
719 call messages_write(real(allocated_mem, real64) , fmt = 'f12.1', units = unit_megabytes, align_left = .true.)
720 call messages_write(' in ')
721 call messages_write(buffer_alloc_count)
722 call messages_write(' buffers were not deallocated.')
723 call messages_fatal()
724 end if
725
726 end if
727
728 pop_sub(accel_end)
729 end subroutine accel_end
730
731 ! ------------------------------------------
732
734 subroutine accel_grid_size_array_i8(n, blocksizes, gridsizes)
735 integer(int64), intent(in) :: n(:)
736 integer(int64), intent(in) :: blocksizes(:)
737 integer(int64), intent(out) :: gridsizes(:)
738
739 integer :: dim, i
740
741 dim = ubound(n, dim=1)
742 assert(dim == ubound(blocksizes, dim=1))
743 assert(dim == ubound(gridsizes, dim=1))
744
745 do i = 1, dim
746 gridsizes(i) = (n(i) + blocksizes(i) - 1_int64) / blocksizes(i)
747 gridsizes(i) = min(gridsizes(i), accel%max_grid_dim(i))
748 end do
749 end subroutine accel_grid_size_array_i8
750
751 ! ------------------------------------------
752
754 subroutine accel_grid_size_array_i4(n, blocksizes, gridsizes)
755 integer, intent(in) :: n(:)
756 integer, intent(in) :: blocksizes(:)
757 integer, intent(out) :: gridsizes(:)
758
759 integer(int64) :: gridsizes64(size(gridsizes))
760
761 call accel_grid_size_array_i8(int(n(:), int64), int(blocksizes(:), int64), gridsizes64)
762
763 gridsizes = int(gridsizes64, int32)
764 end subroutine accel_grid_size_array_i4
765
766 ! ------------------------------------------
767
769 subroutine accel_grid_size_i8(n, blocksizes, gridsizes)
770 integer(int64), intent(in) :: n
771 integer(int64), intent(in) :: blocksizes
772 integer(int64), intent(out) :: gridsizes
773
774 integer(int64) :: temp(1)
776 call accel_grid_size_array_i8( (/n/), (/blocksizes/), temp)
777
778 gridsizes = temp(1)
779 end subroutine accel_grid_size_i8
780
781 ! ------------------------------------------
782
784 subroutine accel_grid_size_i4(n, blocksizes, gridsizes)
785 integer, intent(in) :: n
786 integer, intent(in) :: blocksizes
787 integer, intent(out) :: gridsizes
788
789 integer(int64) :: temp(1)
790
791 call accel_grid_size_array_i8(int((/n/), int64), int((/blocksizes/), int64), temp)
792
793 gridsizes = int(temp(1), int32)
794 end subroutine accel_grid_size_i4
796! ------------------------------------------
797
801 subroutine accel_grid_size_extend_dim_i8(n, pack_size, gridsizes, blocksizes, kernel)
802 integer(int64), intent(in) :: n
803 integer(int64), intent(in) :: pack_size
804 integer(int64), dimension(3), intent(out) :: gridsizes
805 integer(int64), dimension(3), intent(out) :: blocksizes
806 type(accel_kernel_t), optional, intent(inout) :: kernel
807
808 integer(int64) :: bsize, dim2, dim3
809 integer(int64), dimension(3) :: nn
811 if(present(kernel)) then
812 bsize = accel_kernel_block_size(kernel)/pack_size
813 else
814 bsize = accel_max_block_size()/pack_size
815 end if
816
817 dim3 = n/(accel_max_size_per_dim(2)*bsize) + 1
818 dim2 = min(accel_max_size_per_dim(2)*bsize, pad(n, bsize))
819
820 nn = (/pack_size, dim2, dim3/)
821 blocksizes = (/pack_size, bsize, 1_int64/)
822
823 call accel_grid_size(nn, blocksizes, gridsizes)
824 end subroutine accel_grid_size_extend_dim_i8
826 ! ------------------------------------------
827
831 subroutine accel_grid_size_extend_dim_i4(n, pack_size, gridsizes, blocksizes, kernel)
832 integer, intent(in) :: n
833 integer, intent(in) :: pack_size
834 integer, dimension(3), intent(out) :: gridsizes
835 integer, dimension(3), intent(out) :: blocksizes
836 type(accel_kernel_t), optional, intent(inout) :: kernel
837
838 integer(int64) :: gridsizes64(3), blocksizes64(3)
839
840 call accel_grid_size_extend_dim_i8(int(n, int64), int(pack_size, int64), &
841 gridsizes64, blocksizes64, kernel=kernel)
843 gridsizes = int(gridsizes64, int32)
844 blocksizes = int(blocksizes64, int32)
845 end subroutine accel_grid_size_extend_dim_i4
846
847 ! ------------------------------------------
848
849 integer(int64) function accel_padded_size_i8(nn) result(psize)
850 integer(int64), intent(in) :: nn
851
852 integer(int64) :: modnn, bsize
853
854 psize = nn
855
856 if (accel_is_enabled()) then
857
858 bsize = accel_max_block_size()
859
860 psize = nn
861 modnn = mod(nn, bsize)
862 if (modnn /= 0) psize = psize + bsize - modnn
863
864 end if
865
866 end function accel_padded_size_i8
867
868 ! ------------------------------------------
869
870 integer(int32) function accel_padded_size_i4(nn) result(psize)
871 integer(int32), intent(in) :: nn
873 psize = int(accel_padded_size_i8(int(nn, int64)), int32)
874
875 end function accel_padded_size_i4
876
877 ! ------------------------------------------
878
879 subroutine accel_create_buffer_4(this, flags, type, size, set_zero, async)
880 type(accel_mem_t), intent(inout) :: this
881 integer, intent(in) :: flags
882 type(type_t), intent(in) :: type
883 integer, intent(in) :: size
884 logical, optional, intent(in) :: set_zero
885 logical, optional, intent(in) :: async
886
887 call accel_create_buffer_8(this, flags, type, int(size, int64), set_zero, async)
888 end subroutine accel_create_buffer_4
889
890 ! ------------------------------------------
891
892 subroutine accel_create_buffer_8(this, flags, type, size, set_zero, async)
893 type(accel_mem_t), intent(inout) :: this
894 integer, intent(in) :: flags
895 type(type_t), intent(in) :: type
896 integer(int64), intent(in) :: size
897 logical, optional, intent(in) :: set_zero
898 logical, optional, intent(in) :: async
899
900 integer(int64) :: fsize
901 logical :: found
902 integer(int64) :: initialize_buffers
903
904 push_sub(accel_create_buffer_8)
905
906 this%type = type
907 this%size = size
908 this%flags = flags
909 fsize = int(size, int64)*types_get_size(type)
910 this%allocated = .true.
912 if (fsize > 0) then
913
914 call alloc_cache_get(memcache, fsize, found, this%mem)
915
916 if (.not. found) then
917#ifdef HAVE_CUDA
918 if(optional_default(async, .false.)) then
919 call cuda_mem_alloc_async(this%mem, fsize)
920 else
921 call cuda_mem_alloc(this%mem, fsize)
922 end if
923#endif
924 end if
925
926 buffer_alloc_count = buffer_alloc_count + 1
927 allocated_mem = allocated_mem + fsize
928
929 end if
930
931 if (present(set_zero)) then
932 initialize_buffers = merge(option__initializegpubuffers__yes, option__initializegpubuffers__no, set_zero)
933 else
934 initialize_buffers = accel%initialize_buffers
935 end if
936 select case (initialize_buffers)
937 case (option__initializegpubuffers__yes)
938 call accel_set_buffer_to(this, type, int(z'00', int8), size, async=async)
939 case (option__initializegpubuffers__nan)
940 call accel_set_buffer_to(this, type, int(z'FF', int8), size, async=async)
941 end select
942
943 pop_sub(accel_create_buffer_8)
944 end subroutine accel_create_buffer_8
945
946 ! ------------------------------------------
947
948 subroutine accel_free_buffer(this, async)
949 type(accel_mem_t), intent(inout) :: this
950 logical, optional, intent(in) :: async
951
952 logical :: put
953 integer(int64) :: fsize
954
955 push_sub(accel_free_buffer)
956
957 if (this%size > 0) then
958
959 fsize = int(this%size, int64)*types_get_size(this%type)
960
961 call alloc_cache_put(memcache, fsize, this%mem, put)
962
963 if (.not. put) then
964#ifdef HAVE_CUDA
965 if (optional_default(async, .false.)) then
966 call cuda_mem_free_async(this%mem)
967 else
968 call cuda_mem_free(this%mem)
969 end if
970#endif
971 end if
972
973 buffer_alloc_count = buffer_alloc_count - 1
974 allocated_mem = allocated_mem + fsize
975
976 end if
977
978 this%size = 0
979 this%flags = 0
980
981 this%allocated = .false.
982
983 pop_sub(accel_free_buffer)
984 end subroutine accel_free_buffer
985
986 ! ------------------------------------------
987
991 subroutine accel_move_buffer(buffer_from, buffer_to)
992 type(accel_mem_t), intent(inout) :: buffer_from
993 type(accel_mem_t), intent(inout) :: buffer_to
994
995 push_sub(accel_move_buffer)
996
997 ! Can not move an allocated buffer, the destination buffer should be empty
998 assert(.not. accel_buffer_is_allocated(buffer_to))
999
1000 buffer_to%mem = buffer_from%mem
1001 buffer_to%size = buffer_from%size
1002 buffer_to%type = buffer_from%type
1003 buffer_to%flags = buffer_from%flags
1004 buffer_to%allocated = buffer_from%allocated
1005
1006 call accel_detach_buffer(buffer_from)
1007
1008 pop_sub(accel_move_buffer)
1009 end subroutine accel_move_buffer
1010
1011 ! ------------------------------------------
1012
1017 subroutine accel_detach_buffer(this)
1018 type(accel_mem_t), intent(inout) :: this
1019
1020 push_sub(accel_detach_buffer)
1021
1022 this%mem = c_null_ptr
1023 this%size = 0
1024 this%type = type_none
1025 this%flags = 0
1026 this%allocated = .false.
1027
1028 pop_sub(accel_detach_buffer)
1029 end subroutine accel_detach_buffer
1030
1031 ! ------------------------------------------------------
1033 ! Check if the temporary buffers are the right size, if not reallocate them
1034 subroutine accel_ensure_buffer_size_4(buffer, flags, type, required_size, set_zero, async)
1035 type(accel_mem_t), intent(inout) :: buffer
1036 integer, intent(in) :: flags
1037 type(type_t), intent(in) :: type
1038 integer, intent(in) :: required_size
1039 logical, intent(in) :: set_zero
1040 logical, optional, intent(in) :: async
1041
1042 call accel_ensure_buffer_size_8(buffer, flags, type, int(required_size, int64), set_zero, async)
1043 end subroutine accel_ensure_buffer_size_4
1044
1045 ! ------------------------------------------
1046
1053 subroutine accel_ensure_buffer_size_8(buffer, flags, type, required_size, set_zero, async)
1054 type(accel_mem_t), intent(inout) :: buffer
1055 integer, intent(in) :: flags
1056 type(type_t), intent(in) :: type
1057 integer(int64), intent(in) :: required_size
1058 logical, intent(in) :: set_zero
1059 logical, optional, intent(in) :: async
1060
1062
1063
1064 if (accel_buffer_is_allocated(buffer) .and. buffer%size < required_size) then
1065 call accel_free_buffer(buffer, async=optional_default(async, .false.))
1066 end if
1067
1068 if (.not. accel_buffer_is_allocated(buffer)) then
1069 call accel_create_buffer(buffer, flags, type, required_size, set_zero=set_zero, async=optional_default(async, .false.))
1070 end if
1071
1073 end subroutine accel_ensure_buffer_size_8
1074
1075 ! ------------------------------------------
1076
1077 logical pure function accel_buffer_is_allocated(this) result(allocated)
1078 type(accel_mem_t), intent(in) :: this
1079
1080 allocated = this%allocated
1081 end function accel_buffer_is_allocated
1082
1083 ! -----------------------------------------
1084
1085 subroutine accel_finish()
1086 ! no push_sub, called too frequently
1087
1088 if (accel_is_enabled()) then
1089#ifdef HAVE_CUDA
1091#endif
1092 end if
1093 end subroutine accel_finish
1095 ! ------------------------------------------
1096
1097 subroutine accel_set_kernel_arg_buffer(kernel, narg, buffer)
1098 type(accel_kernel_t), intent(inout) :: kernel
1099 integer, intent(in) :: narg
1100 type(accel_mem_t), intent(in) :: buffer
1101
1102 assert(accel_buffer_is_allocated(buffer))
1103
1104 ! no push_sub, called too frequently
1105#ifdef HAVE_CUDA
1106 call cuda_kernel_set_arg_buffer(kernel%arguments, buffer%mem, narg)
1107#endif
1108
1109 end subroutine accel_set_kernel_arg_buffer
1110
1111 ! ------------------------------------------
1112
1119 subroutine accel_kernel_run_8(kernel, gridsizes, blocksizes, shared_memory_size)
1120 type(accel_kernel_t), intent(inout) :: kernel
1121 integer(int64), intent(in) :: gridsizes(:)
1122 integer(int64), intent(in) :: blocksizes(:)
1123 integer(int64), optional, intent(in) :: shared_memory_size
1124
1125 integer :: dim
1126 integer(int64) :: gsizes(1:3)
1127 integer(int64) :: bsizes(1:3)
1128
1129 ! no push_sub, called too frequently
1130
1131 ! CUDA needs all dimensions
1132 gsizes = 1
1133 bsizes = 1
1134
1135 dim = ubound(gridsizes, dim=1)
1136
1137 assert(dim == ubound(blocksizes, dim=1))
1139 ! if one size is zero, there is nothing to do
1140 if (any(gridsizes == 0)) return
1141
1142 assert(all(blocksizes > 0))
1143
1144 gsizes(1:dim) = gridsizes(1:dim)
1145 bsizes(1:dim) = blocksizes(1:dim)
1146
1147#ifdef HAVE_CUDA
1148 ! Maximum dimension of a block
1149 if (any(bsizes(1:3) > accel%max_block_dim(1:3))) then
1150 message(1) = "Maximum dimension of a block too large in kernel "//trim(kernel%kernel_name)
1151 message(2) = "The following conditions should be fulfilled:"
1152 write(message(3), "(A, I8, A, I8)") "Dim 1: ", bsizes(1), " <= ", accel%max_block_dim(1)
1153 write(message(4), "(A, I8, A, I8)") "Dim 2: ", bsizes(2), " <= ", accel%max_block_dim(2)
1154 write(message(5), "(A, I8, A, I8)") "Dim 3: ", bsizes(3), " <= ", accel%max_block_dim(3)
1155 message(6) = "This is an internal error, please contact the developers."
1156 call messages_fatal(6)
1157 end if
1158
1159
1160 ! Maximum number of threads per block
1161 if (product(bsizes) > accel_max_block_size()) then
1162 message(1) = "Maximum number of threads per block too large in kernel "//trim(kernel%kernel_name)
1163 message(2) = "The following condition should be fulfilled:"
1164 write(message(3), "(I8, A, I8)") product(bsizes), " <= ", accel_max_block_size()
1165 message(4) = "This is an internal error, please contact the developers."
1166 call messages_fatal(4)
1167 end if
1168
1169 ! Maximum dimensions of the grid of thread block
1170 if (any(gsizes(1:3) > accel%max_grid_dim(1:3))) then
1171 message(1) = "Maximum dimension of grid too large in kernel "//trim(kernel%kernel_name)
1172 message(2) = "The following conditions should be fulfilled:"
1173 write(message(3), "(A, I8, A, I10)") "Dim 1: ", gsizes(1), " <= ", accel%max_grid_dim(1)
1174 write(message(4), "(A, I8, A, I10)") "Dim 2: ", gsizes(2), " <= ", accel%max_grid_dim(2)
1175 write(message(5), "(A, I8, A, I10)") "Dim 3: ", gsizes(3), " <= ", accel%max_grid_dim(3)
1176 message(6) = "This is an internal error, please contact the developers."
1177 call messages_fatal(6)
1178 end if
1179
1180 if(present(shared_memory_size)) then
1181
1182 if (shared_memory_size > accel%shared_memory_size) then
1183 message(1) = "Shared memory too large in kernel "//trim(kernel%kernel_name)
1184 message(2) = "The following condition should be fulfilled:"
1185 message(3) = "Requested shared memory <= Available shared memory"
1186 write(message(4), '(a,f12.6,a)') "Requested shared memory: ", real(shared_memory_size, real64) /1024.0, " Kb"
1187 write(message(5), '(a,f12.6,a)') "Available shared memory: ", real(accel%shared_memory_size, real64) /1024.0, " Kb"
1188 message(6) = "This is an internal error, please contact the developers."
1189 call messages_fatal(6)
1190 else if (shared_memory_size <= 0) then
1191 message(1) = "Invalid shared memory size in kernel "//trim(kernel%kernel_name)
1192 write(message(2), '(a,f12.6,a)') "Shared memory size requested: ", real(shared_memory_size, real64) /1024.0, " Kb"
1193 message(3) = "This is an internal error, please contact the developers."
1194 call messages_fatal(3)
1195 end if
1196 end if
1197
1198 call cuda_launch_kernel(kernel%cuda_kernel, gsizes(1), bsizes(1), &
1199 optional_default(shared_memory_size, 0_int64), kernel%arguments)
1200#endif
1201
1202 end subroutine accel_kernel_run_8
1203
1204 ! -----------------------------------------------
1205
1211
1212 subroutine accel_kernel_run_4(kernel, gridsizes, blocksizes, shared_memory_size)
1213 type(accel_kernel_t), intent(inout) :: kernel
1214 integer, intent(in) :: gridsizes(:)
1215 integer, intent(in) :: blocksizes(:)
1216 integer(int64), optional, intent(in) :: shared_memory_size
1217
1218 call accel_kernel_run_8(kernel, int(gridsizes, int64), int(blocksizes, int64), shared_memory_size)
1219
1220 end subroutine accel_kernel_run_4
1221
1222 ! -----------------------------------------------
1223
1224 integer pure function accel_max_block_size() result(max_block_size)
1225 max_block_size = accel%max_block_size
1226 end function accel_max_block_size
1227
1228 ! -----------------------------------------------
1229
1230 integer function accel_kernel_block_size(kernel) result(block_size)
1231 type(accel_kernel_t), intent(inout) :: kernel
1232
1233#ifdef HAVE_CUDA
1234 integer :: max_block_size
1235#endif
1236
1237 block_size = 0
1238
1239#ifdef HAVE_CUDA
1240 call cuda_kernel_max_threads_per_block(kernel%cuda_kernel, max_block_size)
1241 if (debug%info .and. max_block_size /= accel%max_block_size) then
1242 write(message(1), "(A, I5, A)") "A kernel can use only less threads per block (", max_block_size, ")", &
1243 "than available on the device (", accel%max_block_size, ")"
1244 call messages_info(1)
1245 end if
1246
1247 ! recommended number of threads per block is 256 according to the CUDA best practice guide
1248 ! see https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#thread-and-block-heuristics
1249 block_size = 256
1250
1251 ! make sure we do not use more threads per block than available for this kernel
1252 block_size = min(block_size, max_block_size)
1253#endif
1254
1255 end function accel_kernel_block_size
1256
1257 ! ----------------------------------------------------
1258
1260 subroutine accel_copy_buffer(dest, src, type, nval, offset_dest, offset_src, async)
1261 type(accel_mem_t), intent(inout) :: dest
1262 type(accel_mem_t), intent(in) :: src
1263 type(type_t), intent(in) :: type
1264 integer(int64), intent(in) :: nval
1265 integer(int64), optional, intent(in) :: offset_dest
1266 integer(int64), optional, intent(in) :: offset_src
1267 logical, optional, intent(in) :: async
1268
1269 integer(int64) :: type_size, offset_dest_, offset_src_
1270
1272 call profiling_in("ACCEL_COPY_BUFFER")
1273
1274 if (nval == 0) then
1275 call profiling_out("ACCEL_COPY_BUFFER")
1276 pop_sub(accel_copy_buffer)
1277 return
1278 end if
1279 assert(nval > 0)
1280
1281 type_size = types_get_size(type)
1282
1283 offset_dest_ = 0_int64
1284 if (present(offset_dest)) offset_dest_ = offset_dest*type_size
1285 offset_src_ = 0_int64
1286 if (present(offset_src)) offset_src_ = offset_src*type_size
1287
1288 assert(offset_dest_ + nval*type_size <= int(dest%size, int64)*types_get_size(dest%type))
1289 assert(offset_src_ + nval*type_size <= int(src%size, int64)*types_get_size(src%type))
1290
1291 call cuda_memcpy_dtod(dest%mem, src%mem, nval*type_size, offset_dest_, offset_src_)
1292
1293 if (.not. optional_default(async, .false.)) call accel_finish()
1294
1295 call profiling_out("ACCEL_COPY_BUFFER")
1296 pop_sub(accel_copy_buffer)
1297 end subroutine accel_copy_buffer
1298
1299 ! ----------------------------------------------------
1300
1301 subroutine accel_set_buffer_to(buffer, type, val, nval, offset, async)
1302 type(accel_mem_t), intent(inout) :: buffer
1303 type(type_t), intent(in) :: type
1304 integer(int8), intent(in) :: val
1305 integer(int64), intent(in) :: nval
1306 integer(int64), optional, intent(in) :: offset
1307 logical, optional, intent(in) :: async
1308
1309 integer(int64) :: nval_, offset_, type_size
1310
1311 push_sub(accel_set_buffer_to)
1313 if (nval == 0) then
1314 pop_sub(accel_set_buffer_to)
1315 return
1316 end if
1317 assert(nval > 0)
1318
1319 if (present(offset)) then
1320 assert(offset >= 0)
1321 if(offset > buffer%size) then
1322 pop_sub(accel_set_buffer_to)
1323 return
1324 end if
1325 end if
1326
1327 type_size = types_get_size(type)
1329 nval_ = nval*type_size
1330
1331 offset_ = 0_int64
1332 if (present(offset)) offset_ = offset*type_size
1333
1334 call cuda_mem_set_async(buffer%mem, val, nval_, offset_)
1335 if(.not. optional_default(async, .false.)) call accel_finish()
1336
1337 pop_sub(accel_set_buffer_to)
1338 end subroutine accel_set_buffer_to
1339
1340 ! ----------------------------------------------------
1341
1342 subroutine accel_set_buffer_to_zero_i8(buffer, type, nval, offset, async)
1343 type(accel_mem_t), intent(inout) :: buffer
1344 type(type_t), intent(in) :: type
1345 integer(int64), intent(in) :: nval
1346 integer(int64), optional, intent(in) :: offset
1347 logical, optional, intent(in) :: async
1350
1351 call accel_set_buffer_to(buffer, type, int(z'00', int8), nval, offset, async)
1352
1354 end subroutine accel_set_buffer_to_zero_i8
1355
1356 ! ----------------------------------------------------
1357
1358 subroutine accel_set_buffer_to_zero_i4(buffer, type, nval, offset, async)
1359 type(accel_mem_t), intent(inout) :: buffer
1360 type(type_t), intent(in) :: type
1361 integer(int32), intent(in) :: nval
1362 integer(int32), optional, intent(in) :: offset
1363 logical, optional, intent(in) :: async
1364
1366
1367 if (present(offset)) then
1368 call accel_set_buffer_to_zero_i8(buffer, type, int(nval, int64), int(offset, int64), async=async)
1369 else
1370 call accel_set_buffer_to_zero_i8(buffer, type, int(nval, int64), async=async)
1371 end if
1372
1374 end subroutine accel_set_buffer_to_zero_i4
1375
1376 ! ----------------------------------------------------
1377
1378 subroutine accel_check_bandwidth()
1379 integer :: itime
1380 integer, parameter :: times = 10
1381 integer :: size
1382 real(real64) :: time, stime
1383 real(real64) :: read_bw, write_bw
1384 type(accel_mem_t) :: buff
1385 real(real64), allocatable :: data(:)
1386
1387 call messages_new_line()
1388 call messages_write('Info: Benchmarking the bandwidth between main memory and device memory')
1389 call messages_new_line()
1390 call messages_info()
1391
1392 call messages_write(' Buffer size Read bw Write bw')
1393 call messages_new_line()
1394 call messages_write(' [MiB] [MiB/s] [MiB/s]')
1395 call messages_info()
1396
1397 size = 15000
1398 do
1399 safe_allocate(data(1:size))
1400 call accel_create_buffer(buff, accel_mem_read_write, type_float, size)
1401
1402 stime = loct_clock()
1403 do itime = 1, times
1404 call accel_write_buffer(buff, size, data)
1405 call accel_finish()
1406 end do
1407 time = (loct_clock() - stime)/real(times, real64)
1408
1409 write_bw = real(size, real64) *8.0_real64/time
1410
1411 stime = loct_clock()
1412 do itime = 1, times
1413 call accel_read_buffer(buff, size, data)
1414 end do
1415 call accel_finish()
1416
1417 time = (loct_clock() - stime)/real(times, real64)
1418 read_bw = real(size, real64) *8.0_real64/time
1419
1420 call messages_write(size*8.0_real64/1024.0_real64**2)
1421 call messages_write(write_bw/1024.0_real64**2, fmt = '(f10.1)')
1422 call messages_write(read_bw/1024.0_real64**2, fmt = '(f10.1)')
1423 call messages_info()
1424
1425 call accel_free_buffer(buff)
1426
1427 safe_deallocate_a(data)
1429 size = int(size*2.0)
1430
1431 if (size > 50000000) exit
1432 end do
1433 end subroutine accel_check_bandwidth
1434
1435 !------------------------------------------------------------
1436
1437 subroutine accel_kernel_global_init()
1438
1439 push_sub(accel_kernel_global_init)
1440
1441 nullify(head)
1442
1443 call cuda_program_map_init(accel%program_map)
1444
1445 call accel_kernel_list()
1446
1448 end subroutine accel_kernel_global_init
1449
1450 !------------------------------------------------------------
1451
1458 subroutine accel_kernel_list()
1459
1460 push_sub(accel_kernel_list)
1461
1462 call accel_program_add('axpy.cu', 'axpy<double>')
1463 call accel_program_add('axpy.cu', 'axpy<complex<double>>')
1464 call accel_program_add('axpy.cu', 'axpy<float>')
1465 call accel_program_add('axpy.cu', 'axpy<complex<float>>')
1466 call accel_program_add('axpy.cu', 'axpby<double>')
1467 call accel_program_add('axpy.cu', 'axpby<complex<double>>')
1468 call accel_program_add('axpy.cu', 'scal2v<double>')
1469 call accel_program_add('axpy.cu', 'scal2v<complex<double>, Conjugation::No>')
1470 call accel_program_add('axpy.cu', 'scal2v<complex<double>, Conjugation::Yes>')
1471 call accel_program_add('axpy.cu', 'axpy_vec<double>')
1472 call accel_program_add('axpy.cu', 'axpy_vec<complex<double>>')
1473 call accel_program_add('axpy.cu', 'axpy_vec<float>')
1474 call accel_program_add('axpy.cu', 'axpy_vec<complex<float>>')
1475 call accel_program_add('axpy.cu', 'scal_vec<double>')
1476 call accel_program_add('axpy.cu', 'scal_vec<complex<double>>')
1477 call accel_program_add('axpy.cu', 'scal_vec<float>')
1478 call accel_program_add('axpy.cu', 'scal_vec<complex<float>>')
1479 call accel_program_add('axpy.cu', 'xpay_vec<double>')
1480 call accel_program_add('axpy.cu', 'xpay_vec<complex<double>>')
1481 call accel_program_add('axpy.cu', 'xpay_vec<float>')
1482 call accel_program_add('axpy.cu', 'xpay_vec<complex<float>>')
1483 call accel_program_add('axpy.cu', &
1484 'batch_axpy_function<double, DimSpin::D1>')
1485 call accel_program_add('axpy.cu', &
1486 'batch_axpy_function<double, DimSpin::D2>')
1487 call accel_program_add('axpy.cu', &
1488 'batch_axpy_function<complex<double>, DimSpin::D1>')
1489 call accel_program_add('axpy.cu', &
1490 'batch_axpy_function<complex<double>, DimSpin::D2>')
1491 call accel_program_add('axpy.cu', &
1492 'batch_axpy_function<float, DimSpin::D1>')
1493 call accel_program_add('axpy.cu', &
1494 'batch_axpy_function<float, DimSpin::D2>')
1495 call accel_program_add('axpy.cu', &
1496 'batch_axpy_function<complex<float>, DimSpin::D1>')
1497 call accel_program_add('axpy.cu', &
1498 'batch_axpy_function<complex<float>, DimSpin::D2>')
1499 call accel_program_add('axpy.cu', &
1500 'batch_ax_function_py<double, DimSpin::D1>')
1501 call accel_program_add('axpy.cu', &
1502 'batch_ax_function_py<double, DimSpin::D2>')
1503 call accel_program_add('axpy.cu', &
1504 'batch_ax_function_py<complex<double>, DimSpin::D1>')
1505 call accel_program_add('axpy.cu', &
1506 'batch_ax_function_py<complex<double>, DimSpin::D2>')
1507 call accel_program_add('axpy.cu', &
1508 'batch_ax_function_py<float, DimSpin::D1>')
1509 call accel_program_add('axpy.cu', &
1510 'batch_ax_function_py<float, DimSpin::D2>')
1511 call accel_program_add('axpy.cu', &
1512 'batch_ax_function_py<complex<float>, DimSpin::D1>')
1513 call accel_program_add('axpy.cu', &
1514 'batch_ax_function_py<complex<float>, DimSpin::D2>')
1515
1516 call accel_program_add('batch_mul.cu', 'mul_batch<double>')
1517 call accel_program_add('batch_mul.cu', 'mul_mf<double, double>')
1518 call accel_program_add('batch_mul.cu', 'mul_batch<complex<double>, Conjugation::No>')
1519 call accel_program_add('batch_mul.cu', 'mul_batch<complex<double>, Conjugation::Yes>')
1520 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, double, Conjugation::No>')
1521 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, double, Conjugation::Yes>')
1522 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, complex<double>, Conjugation::No>')
1523 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, complex<double>, Conjugation::Yes>')
1524
1525 call accel_program_add('boundaries.cu', 'boundaries_periodic<double>')
1526 call accel_program_add('boundaries.cu', 'boundaries_periodic_corr<double>')
1527 call accel_program_add('boundaries.cu', 'boundaries_periodic_recv<double>')
1528 call accel_program_add('boundaries.cu', 'boundaries_periodic_recv_corr<double>')
1529 call accel_program_add('boundaries.cu', 'boundaries_periodic_send<double>')
1530
1531 call accel_program_add('copy.cu', 'add_with_map<double>')
1532 call accel_program_add('copy.cu', 'copy<double>')
1533 call accel_program_add('copy.cu', 'copy<float>')
1534 call accel_program_add('copy.cu', 'copy_complex_to_real<double>')
1535 call accel_program_add('copy.cu', 'copy_real_to_complex<double>')
1536 call accel_program_add('copy.cu', 'copy_with_map<double>')
1537
1538 call accel_program_add('curl.cu', 'curl<double>')
1539 call accel_program_add('curl.cu', 'curl<complex<double>>')
1540
1541 call accel_program_add('density.cu', 'density<double, double>')
1542 call accel_program_add('density.cu', 'density<double, complex<double>>')
1543 call accel_program_add('density.cu', 'current_accumulate<double>')
1544 call accel_program_add('density.cu', 'density_spinors<double>')
1545
1546 call accel_program_add('dftu_projector.cu', &
1547 'dftu_pos_mat_elem<double, double, Indexing::Indirect>')
1548 call accel_program_add('dftu_projector.cu', &
1549 'dftu_pos_mat_elem<double, complex<double>, Indexing::Indirect>')
1550 call accel_program_add('dftu_projector.cu', &
1551 'dftu_pos_mat_elem<double, complex<double>, Indexing::Direct>')
1552 call accel_program_add('dftu_projector.cu', 'dftu_pos_mat_elem_phase<double>')
1553 call accel_program_add('dftu_projector.cu', &
1554 'dftu_pos_mat_elem<double, double, Indexing::Direct>')
1555 call accel_program_add('dftu_projector.cu', &
1556 'dftu_projector_bra<double>')
1557 call accel_program_add('dftu_projector.cu', &
1558 'dftu_projector_bra<complex<double>>')
1559 call accel_program_add('dftu_projector.cu', &
1560 'dftu_projector_bra_submesh<complex<double>>')
1561 call accel_program_add('dftu_projector.cu', &
1562 'dftu_projector_bra_submesh<double>')
1563 call accel_program_add('dftu_projector.cu', &
1564 'dftu_projector_ket<double>')
1565 call accel_program_add('dftu_projector.cu', &
1566 'dftu_projector_ket<complex<double>>')
1567 call accel_program_add('dftu_projector.cu', &
1568 'dftu_projector_ket_submesh<complex<double>>')
1569 call accel_program_add('dftu_projector.cu', &
1570 'dftu_projector_ket_submesh<double>')
1571
1572 call accel_program_add('exchange_local.cu', &
1573 'exchange_accumulate_batch<double, double, DimSpin::D1>')
1574 call accel_program_add('exchange_local.cu', &
1575 'exchange_accumulate_return_batch<double, double, DimSpin::D1>')
1576 call accel_program_add('exchange_local.cu', &
1577 'exchange_codensity_batch<double, DimSpin::D1>')
1578 call accel_program_add('exchange_local.cu', &
1579 'exchange_accumulate_batch<double, double, DimSpin::D2>')
1580 call accel_program_add('exchange_local.cu', &
1581 'exchange_accumulate_return_batch<double, double, DimSpin::D2>')
1582 call accel_program_add('exchange_local.cu', &
1583 'exchange_codensity_batch<double, DimSpin::D2>')
1584 call accel_program_add('exchange_local.cu', &
1585 'exchange_accumulate_batch<double, complex<double>, DimSpin::D1>')
1586 call accel_program_add('exchange_local.cu', &
1587 'exchange_accumulate_return_batch<double, complex<double>, DimSpin::D1>')
1588 call accel_program_add('exchange_local.cu', &
1589 'exchange_codensity_batch<complex<double>, DimSpin::D1>')
1590 call accel_program_add('exchange_local.cu', &
1591 'exchange_accumulate_batch<double, complex<double>, DimSpin::D2>')
1592 call accel_program_add('exchange_local.cu', &
1593 'exchange_accumulate_return_batch<double, complex<double>, DimSpin::D2>')
1594 call accel_program_add('exchange_local.cu', &
1595 'exchange_codensity_batch<complex<double>, DimSpin::D2>')
1596 call accel_program_add('exchange_local.cu', &
1597 'exchange_codensity_batch<float, DimSpin::D1>')
1598 call accel_program_add('exchange_local.cu', &
1599 'exchange_codensity_batch<float, DimSpin::D2>')
1600 call accel_program_add('exchange_local.cu', &
1601 'exchange_codensity_batch<complex<float>, DimSpin::D1>')
1602 call accel_program_add('exchange_local.cu', &
1603 'exchange_codensity_batch<complex<float>, DimSpin::D2>')
1604 call accel_program_add('exchange_local.cu', &
1605 'exchange_accumulate_batch<float, float, DimSpin::D1>')
1606 call accel_program_add('exchange_local.cu', &
1607 'exchange_accumulate_return_batch<float, float, DimSpin::D1>')
1608 call accel_program_add('exchange_local.cu', &
1609 'exchange_accumulate_batch<float, float, DimSpin::D2>')
1610 call accel_program_add('exchange_local.cu', &
1611 'exchange_accumulate_return_batch<float, float, DimSpin::D2>')
1612 call accel_program_add('exchange_local.cu', &
1613 'exchange_accumulate_batch<float, complex<float>, DimSpin::D1>')
1614 call accel_program_add('exchange_local.cu', &
1615 'exchange_accumulate_return_batch<float, complex<float>, DimSpin::D1>')
1616 call accel_program_add('exchange_local.cu', &
1617 'exchange_accumulate_batch<float, complex<float>, DimSpin::D2>')
1618 call accel_program_add('exchange_local.cu', &
1619 'exchange_accumulate_return_batch<float, complex<float>, DimSpin::D2>')
1620
1621 call accel_program_add('forces.cu', 'density_gradient<double, double>')
1622 call accel_program_add('forces.cu', 'density_gradient<double, complex<double>>')
1623
1624 call accel_program_add('get_points.cu', 'get_selected_points<double>')
1625
1626 call accel_program_add('ghost.cu', 'ghost_reorder<double>')
1627
1628 call accel_program_add('mesh_batch.cu', 'zdot_matrix_spinors<double>')
1629
1630 call accel_program_add('mesh_batch_single.cu', 'batch_dotpv_partial<double>')
1631 call accel_program_add('mesh_batch_single.cu', &
1632 'batch_dotpv_reduce<double, double, DimSpin::D1>')
1633 call accel_program_add('mesh_batch_single.cu', &
1634 'batch_dotpv_reduce<double, double, DimSpin::D2>')
1635 call accel_program_add('mesh_batch_single.cu', &
1636 'batch_mf_dotp<double, DimSpin::D1>')
1637 call accel_program_add('mesh_batch_single.cu', &
1638 'batch_mf_dotp<double, DimSpin::D2>')
1639 call accel_program_add('mesh_batch_single.cu', 'batch_dotpv_partial<complex<double>>')
1640 call accel_program_add('mesh_batch_single.cu', &
1641 'batch_dotpv_reduce<double, complex<double>, DimSpin::D1>')
1642 call accel_program_add('mesh_batch_single.cu', &
1643 'batch_dotpv_reduce<double, complex<double>, DimSpin::D2>')
1644 call accel_program_add('mesh_batch_single.cu', &
1645 'batch_mf_dotp<complex<double>, DimSpin::D1>')
1646 call accel_program_add('mesh_batch_single.cu', &
1647 'batch_mf_dotp<complex<double>, DimSpin::D2>')
1648
1649 call accel_program_add('mesh_interpolate.cu', &
1650 'mesh_interpolate<double, double, Dim::D1>')
1651 call accel_program_add('mesh_interpolate.cu', &
1652 'mesh_interpolate<double, double, Dim::D2>')
1653 call accel_program_add('mesh_interpolate.cu', &
1654 'mesh_interpolate<double, double, Dim::D3>')
1655 call accel_program_add('mesh_interpolate.cu', &
1656 'mesh_interpolate<double, complex<double>, Dim::D1>')
1657 call accel_program_add('mesh_interpolate.cu', &
1658 'mesh_interpolate<double, complex<double>, Dim::D2>')
1659 call accel_program_add('mesh_interpolate.cu', &
1660 'mesh_interpolate<double, complex<double>, Dim::D3>')
1661
1662 call accel_program_add('mesh_to_cube.cu', 'cube_to_mesh_batch<double>')
1663 call accel_program_add('mesh_to_cube.cu', 'mesh_to_cube_batch<double>')
1664 call accel_program_add('mesh_to_cube.cu', 'cube_to_mesh_batch<complex<double>>')
1665 call accel_program_add('mesh_to_cube.cu', 'mesh_to_cube_batch<complex<double>>')
1666 call accel_program_add('mesh_to_cube.cu', 'submesh_to_cube<double>')
1667 call accel_program_add('mesh_to_cube.cu', 'cube_to_submesh<double>')
1668 call accel_program_add('mesh_to_cube.cu', 'submesh_to_cube<complex<double>>')
1669 call accel_program_add('mesh_to_cube.cu', 'cube_to_submesh<complex<double>>')
1670 call accel_program_add('mesh_to_cube.cu', 'cube_to_mesh_batch<float>')
1671 call accel_program_add('mesh_to_cube.cu', 'mesh_to_cube_batch<float>')
1672 call accel_program_add('mesh_to_cube.cu', 'cube_to_mesh_batch<complex<float>>')
1673 call accel_program_add('mesh_to_cube.cu', 'mesh_to_cube_batch<complex<float>>')
1674
1675 call accel_program_add('mul.cu', 'zmul_batch<double, double>')
1676 call accel_program_add('mul.cu', 'zmul_batch<double, complex<double>>')
1677 call accel_program_add('mul.cu', 'zmul_batch<float, float>')
1678 call accel_program_add('mul.cu', 'zmul_batch<float, complex<float>>')
1679
1680 call accel_program_add('operate.cu', 'operate<double>')
1681 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Direct>')
1682 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Indirect>')
1683 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Direct, Symmetry::Antisymmetric>')
1684 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Direct, Symmetry::Symmetric>')
1685 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Indirect, Symmetry::Antisymmetric>')
1686 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Indirect, Symmetry::Symmetric>')
1687
1688 call accel_program_add('pack.cu', 'pack<double>')
1689 call accel_program_add('pack.cu', 'unpack<double>')
1690 call accel_program_add('pack.cu', 'pack<complex<double>>')
1691 call accel_program_add('pack.cu', 'unpack<complex<double>>')
1692 call accel_program_add('pack.cu', 'pack<float>')
1693 call accel_program_add('pack.cu', 'unpack<float>')
1694 call accel_program_add('pack.cu', 'pack<complex<float>>')
1695 call accel_program_add('pack.cu', 'unpack<complex<float>>')
1696
1697 call accel_program_add('pes.cu', 'zpes_flux_sph_integrate<double>')
1698 call accel_program_add('pes.cu', 'zpes_flux_sph_integxx<double>')
1699 call accel_program_add('pes.cu', 'zpes_flux_sph_integxx_2<double>')
1700
1701 call accel_program_add('phase.cu', 'phase<double>')
1702 call accel_program_add('phase.cu', 'phase_hamiltonian<double>')
1703 call accel_program_add('phase.cu', 'update_phases<double, Dim::D1>')
1704 call accel_program_add('phase.cu', 'update_phases<double, Dim::D2>')
1705 call accel_program_add('phase.cu', 'update_phases<double, Dim::D3>')
1706
1707 call accel_program_add('phase_spiral.cu', 'phase_spiral_apply<double>')
1708
1709 call accel_program_add('pml.cu', 'pml_apply<double>')
1710 call accel_program_add('pml.cu', 'pml_apply_new<double>')
1711 call accel_program_add('pml.cu', 'pml_copy<double>')
1712 call accel_program_add('pml.cu', 'pml_update_conv<double>')
1713 call accel_program_add('pml.cu', 'pml_update_new<double>')
1714
1715 call accel_program_add('points.cu', 'get_points<double>')
1716 call accel_program_add('points.cu', 'set_points<double>')
1717
1718 call accel_program_add('precision_copy.cu', 'precision_copy<double, float>')
1719 call accel_program_add('precision_copy.cu', 'precision_copy<float, double>')
1720 call accel_program_add('precision_copy.cu', &
1721 'precision_copy<complex<double>, complex<float>>')
1722 call accel_program_add('precision_copy.cu', &
1723 'precision_copy<complex<float>, complex<double>>')
1724
1725 call accel_program_add('projector.cu', 'projector_bra_force<double, double>')
1726 call accel_program_add('projector.cu', 'projector_bra_force_phase<double, double>')
1727 call accel_program_add('projector.cu', 'projector_ket<double>')
1728 call accel_program_add('projector.cu', 'projector_ket_phase<double, double>')
1729 call accel_program_add('projector.cu', 'projector_ket_phase_spiral<double, double>')
1730 call accel_program_add('projector.cu', 'dprojector_mix<double>')
1731 call accel_program_add('projector.cu', 'projector_r_vnl_bra<double, double>')
1732 call accel_program_add('projector.cu', 'projector_r_vnl_bra_phase<double, double>')
1733 call accel_program_add('projector.cu', 'projector_r_vnl_ket<double, double>')
1734 call accel_program_add('projector.cu', 'projector_r_vnl_ket_phase<double, double>')
1735 call accel_program_add('projector.cu', 'projector_bra_phase_spiral_gather_all<double>')
1736 call accel_program_add('projector.cu', 'projector_bra_force<double, complex<double>>')
1737 call accel_program_add('projector.cu', 'projector_bra_force_phase<double, complex<double>>')
1738 call accel_program_add('projector.cu', 'projector_ket<complex<double>>')
1739 call accel_program_add('projector.cu', 'projector_ket_phase<double, complex<double>>')
1740 call accel_program_add('projector.cu', 'projector_ket_phase_spiral<double, complex<double>>')
1741 call accel_program_add('projector.cu', 'zprojector_mix<double>')
1742 call accel_program_add('projector.cu', 'projector_r_vnl_bra<double, complex<double>>')
1743 call accel_program_add('projector.cu', 'projector_r_vnl_bra_phase<double, complex<double>>')
1744 call accel_program_add('projector.cu', 'projector_r_vnl_ket<double, complex<double>>')
1745 call accel_program_add('projector.cu', 'projector_r_vnl_ket_phase<double, complex<double>>')
1746 call accel_program_add('projector.cu', 'projector_bra_gather_all<double>')
1747 call accel_program_add('projector.cu', 'projector_bra_gather_all<complex<double>>')
1748 call accel_program_add('projector.cu', 'projector_bra_phase_gather_all<double>')
1749 call accel_program_add('projector.cu', 'projector_bra_scatter_all<double, double>')
1750 call accel_program_add('projector.cu', 'projector_bra_scatter_all<double, complex<double>>')
1751 call accel_program_add('projector.cu', 'projector_bra_scatter_complex_all<double, complex<double>>')
1752
1753 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra<double, double>')
1754 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra_phase<double, double>')
1755 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket<double, double>')
1756 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket_phase<double, double>')
1757 call accel_program_add('projector_commutator.cu', 'dprojector_mix_commutator<double>')
1758 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra<double, complex<double>>')
1759 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra_phase<double, complex<double>>')
1760 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket<double, complex<double>>')
1761 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket_phase<double, complex<double>>')
1762 call accel_program_add('projector_commutator.cu', 'zprojector_mix_commutator<double>')
1763
1764 call accel_program_add('split.cu', 'merge_complex<double>')
1765 call accel_program_add('split.cu', 'merge_complex<float>')
1766 call accel_program_add('split.cu', 'split_complex<double>')
1767 call accel_program_add('split.cu', 'split_complex<float>')
1768
1769 call accel_program_add('symmetrize_batch.cu', &
1770 'symmetrizer_apply_single_batch<double, Conjugation::No>')
1771 call accel_program_add('symmetrize_batch.cu', &
1772 'symmetrizer_apply_single_batch<double, Conjugation::Yes>')
1773 call accel_program_add('symmetrize_batch.cu', &
1774 'symmetrizer_apply_single_batch<complex<double>, Conjugation::No>')
1775 call accel_program_add('symmetrize_batch.cu', &
1776 'symmetrizer_apply_single_batch<complex<double>, Conjugation::Yes>')
1777 call accel_program_add('symmetrize_batch.cu', &
1778 'symmetrizer_apply_single_batch<float, Conjugation::No>')
1779 call accel_program_add('symmetrize_batch.cu', &
1780 'symmetrizer_apply_single_batch<float, Conjugation::Yes>')
1781 call accel_program_add('symmetrize_batch.cu', &
1782 'symmetrizer_apply_single_batch<complex<float>, Conjugation::No>')
1783 call accel_program_add('symmetrize_batch.cu', &
1784 'symmetrizer_apply_single_batch<complex<float>, Conjugation::Yes>')
1785
1786 call accel_program_add('uvw_to_xyz.cu', &
1787 'uvw_to_xyz<double, Dim::D1, double*, int, double*, int>')
1788 call accel_program_add('uvw_to_xyz.cu', &
1789 'uvw_to_xyz<double, Dim::D2, double*, int, double*, int, double*, int, double*, int>')
1790 call accel_program_add('uvw_to_xyz.cu', &
1791 'uvw_to_xyz<double, Dim::D3, double*, int, double*, int, double*, int, double*, int, double*, int, double*, int>')
1792
1793 call accel_program_add('vpsi.cu', 'vpsi<double>')
1794 call accel_program_add('vpsi.cu', 'vpsi_complex<double>')
1795 call accel_program_add('vpsi.cu', 'vpsi_spinors<double>')
1796 call accel_program_add('vpsi.cu', 'vpsi_spinors_complex<double>')
1797
1798 call accel_program_add('xc_dens_block.cu', 'xc_dens_apply_corrections<double>')
1799 call accel_program_add('xc_dens_block.cu', 'xc_dens_extract_block<double>')
1800
1801 pop_sub(accel_kernel_list)
1802 end subroutine accel_kernel_list
1803
1804 !------------------------------------------------------------
1805
1811 subroutine accel_program_add(file_name, name)
1812 character(len=*), intent(in) :: file_name
1813 character(len=*), intent(in) :: name
1814
1815 push_sub(accel_program_add)
1816
1817 call cuda_program_register(accel%program_map, string_f_to_c(trim(file_name)), &
1818 string_f_to_c(trim(name)))
1819
1820 pop_sub(accel_program_add)
1821 end subroutine accel_program_add
1822
1823 !------------------------------------------------------------
1824
1825 subroutine accel_kernel_global_end()
1826 type(accel_kernel_t), pointer :: next_head
1827
1828 push_sub(accel_kernel_global_end)
1829
1830 do
1831 if (.not. associated(head)) exit
1832 next_head => head%next
1834 head => next_head
1835 end do
1836
1837 if (accel_is_enabled()) then
1838 call cuda_program_map_end(accel%program_map)
1839 end if
1840
1842 end subroutine accel_kernel_global_end
1843
1844 !------------------------------------------------------------
1851 subroutine accel_kernel_build(this, file_name, kernel_name, flags)
1852 type(accel_kernel_t), intent(inout) :: this
1853 character(len=*), intent(in) :: file_name
1854 character(len=*), intent(in) :: kernel_name
1855 character(len=*), optional, intent(in) :: flags
1856
1857#ifdef HAVE_CUDA
1858 character(len=1000) :: all_flags
1859#endif
1860
1861 push_sub(accel_kernel_build)
1862
1863 call profiling_in("ACCEL_COMPILE", exclude = .true.)
1864
1865#ifdef HAVE_CUDA
1866 all_flags = '-I'//trim(conf%share)//'/kernels/'//" "//trim(accel%debug_flag)
1867
1868 if (present(flags)) then
1869 all_flags = trim(all_flags)//' '//trim(flags)
1870 end if
1871
1872 call cuda_program_build(accel%program_map, accel%device%cuda_device, &
1873 string_f_to_c(trim(file_name)), string_f_to_c(trim(all_flags)))
1874
1875 call cuda_program_get_kernel(this%cuda_kernel, accel%program_map, &
1876 string_f_to_c(trim(file_name)), string_f_to_c(trim(all_flags)), &
1877 string_f_to_c(trim(kernel_name)))
1878 call cuda_alloc_arg_array(this%arguments)
1879#endif
1880
1881 this%initialized = .true.
1882 this%kernel_name = trim(kernel_name)
1883
1884 call profiling_out("ACCEL_COMPILE")
1885
1886 pop_sub(accel_kernel_build)
1887 end subroutine accel_kernel_build
1888
1889 !------------------------------------------------------------
1891 subroutine accel_kernel_end(this)
1892 type(accel_kernel_t), intent(inout) :: this
1893
1894 push_sub(accel_kernel_end)
1895
1896#ifdef HAVE_CUDA
1897 call cuda_free_arg_array(this%arguments)
1898 call cuda_release_kernel(this%cuda_kernel)
1899 ! modules are not released here, since they are not associated to a kernel
1900#endif
1901
1902 this%initialized = .false.
1903
1904 pop_sub(accel_kernel_end)
1905 end subroutine accel_kernel_end
1906
1907 !------------------------------------------------------------
1908
1909 subroutine accel_kernel_start_call(this, file_name, kernel_name, flags)
1910 type(accel_kernel_t), target, intent(inout) :: this
1911 character(len=*), intent(in) :: file_name
1912 character(len=*), intent(in) :: kernel_name
1913 character(len=*), optional, intent(in) :: flags
1914
1915 push_sub(accel_kernel_start_call)
1916
1917 if (.not. this%initialized) then
1918 call accel_kernel_build(this, file_name, kernel_name, flags)
1919 this%next => head
1920 head => this
1921 end if
1922
1924 end subroutine accel_kernel_start_call
1925
1926 !--------------------------------------------------------------
1927
1928 integer(int64) pure function accel_global_memory_size() result(size)
1929
1930 size = accel%global_memory_size
1931
1932 end function accel_global_memory_size
1933
1934 !--------------------------------------------------------------
1935
1936 integer(int64) pure function accel_shared_memory_size() result(size)
1937
1938 size = accel%shared_memory_size
1939
1940 end function accel_shared_memory_size
1941 !--------------------------------------------------------------
1942
1943 integer pure function accel_max_size_per_dim(dim) result(size)
1944 integer, intent(in) :: dim
1945
1946 size = 0
1947#ifdef HAVE_CUDA
1948 size = 32768
1949 if (dim == 1) size = 2**30
1950#endif
1951 end function accel_max_size_per_dim
1952
1953 ! ------------------------------------------------------
1954
1955 subroutine accel_set_stream(stream_number)
1956 integer, intent(in) :: stream_number
1957
1958 push_sub(accel_set_stream)
1959
1960 if (accel_is_enabled()) then
1961#ifdef HAVE_CUDA
1962 call cuda_set_stream(accel%cuda_stream, stream_number)
1963 ! The stream number selects which of the per-stream BLAS handles the
1964 ! wrappers use; see cublas_init() in src/basic/cublas.cc.
1965 call cublas_set_stream(accel%cuda_stream, stream_number)
1966#endif
1967 end if
1968
1969 pop_sub(accel_set_stream)
1970 end subroutine accel_set_stream
1972 ! ------------------------------------------------------
1973
1974 subroutine accel_get_stream(stream_number)
1975 integer, intent(inout) :: stream_number
1976
1977 push_sub(accel_get_stream)
1978
1979 if (accel_is_enabled()) then
1980#ifdef HAVE_CUDA
1981 call cuda_get_stream(stream_number)
1982#endif
1983 end if
1984
1985 pop_sub(accel_get_stream)
1986 end subroutine accel_get_stream
1987
1988 ! ------------------------------------------------------
1989
1992
1993 if (accel_is_enabled()) then
1994#ifdef HAVE_CUDA
1995 call cuda_synchronize_all_streams()
1996#endif
1997 end if
1998
2000 end subroutine accel_synchronize_all_streams
2001
2002 function daccel_get_pointer_with_offset(buffer, offset) result(buffer_offset)
2003 type(c_ptr), intent(in) :: buffer
2004 integer(int64), intent(in) :: offset
2005 type(c_ptr) :: buffer_offset
2006
2008#ifdef HAVE_CUDA
2009 call cuda_get_pointer_with_offset(buffer, offset, buffer_offset)
2010#else
2011 ! this is needed to make the compiler happy for non-GPU compilations
2012 buffer_offset = buffer
2013#endif
2016
2017 function zaccel_get_pointer_with_offset(buffer, offset) result(buffer_offset)
2018 type(c_ptr), intent(in) :: buffer
2019 integer(int64), intent(in) :: offset
2020 type(c_ptr) :: buffer_offset
2021
2023#ifdef HAVE_CUDA
2024 call cuda_get_pointer_with_offset(buffer, 2_int64*offset, buffer_offset)
2025#else
2026 ! this is needed to make the compiler happy for non-GPU compilations
2027 buffer_offset = buffer
2028#endif
2031
2032 subroutine accel_clean_pointer(buffer)
2033 type(c_ptr), intent(in) :: buffer
2034
2035 push_sub(accel_clean_pointer)
2036#ifdef HAVE_CUDA
2037 call cuda_clean_pointer(buffer)
2038#endif
2039 pop_sub(accel_clean_pointer)
2040 end subroutine accel_clean_pointer
2041
2045 subroutine accel_get_unfolded_size(size, grid_size, thread_block_size)
2046 integer(int64), intent(in) :: size
2047 integer(int64), intent(out) :: grid_size
2048 integer(int64), intent(out) :: thread_block_size
2049
2050 push_sub(accel_get_unfolded_size)
2051#ifdef __HIP_PLATFORM_AMD__
2052 ! not benefitial for AMD chips
2053 grid_size = 1_int64
2054 thread_block_size = size
2055#else
2056 grid_size = size
2057 thread_block_size = accel%warp_size
2058#endif
2060 end subroutine accel_get_unfolded_size
2061
2062#include "undef.F90"
2063#include "real.F90"
2064#include "accel_inc.F90"
2065
2066#include "undef.F90"
2067#include "complex.F90"
2068#include "accel_inc.F90"
2069
2070#include "undef.F90"
2071#include "real32.F90"
2072#include "accel_inc.F90"
2073
2074#include "undef.F90"
2075#include "complex32.F90"
2076#include "accel_inc.F90"
2077
2078#include "undef.F90"
2079#include "integer.F90"
2080#include "accel_inc.F90"
2081
2082#include "undef.F90"
2083#include "integer8.F90"
2084#include "accel_inc.F90"
2085
2086end module accel_oct_m
2087
2088!! Local Variables:
2089!! mode: f90
2090!! coding: utf-8
2091!! End:
subroutine device_info()
Definition: accel.F90:639
subroutine accel_grid_size_i4(n, blocksizes, gridsizes)
Computes the grid size for a given problem size and block size (32-bit version).
Definition: accel.F90:826
subroutine saccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4898
subroutine laccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:8283
subroutine caccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5922
subroutine caccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5340
subroutine zaccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:4058
subroutine, public accel_clean_pointer(buffer)
Definition: accel.F90:1987
subroutine caccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:5486
subroutine accel_kernel_global_end()
Definition: accel.F90:1796
subroutine zaccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3236
subroutine, public accel_get_unfolded_size(size, grid_size, thread_block_size)
Get unfolded size: some kernels (e.g. projectors) unfold the array across warps as an optimization....
Definition: accel.F90:2000
subroutine laccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:8079
subroutine laccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:7838
subroutine saccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:4396
subroutine iaccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:6357
subroutine accel_ensure_buffer_size_4(buffer, flags, type, required_size, set_zero, async)
Definition: accel.F90:1076
pure logical function, public accel_allow_cpu_only()
Definition: accel.F90:424
subroutine caccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6162
subroutine daccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2917
subroutine zaccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3878
subroutine caccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:5819
subroutine daccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2639
subroutine zaccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3965
subroutine caccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:5710
subroutine laccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:7862
subroutine saccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:4238
subroutine saccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4366
subroutine daccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2397
subroutine laccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:7437
subroutine caccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:5309
subroutine saccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4469
subroutine daccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2369
subroutine saccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:4257
subroutine caccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:5887
subroutine laccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:8166
subroutine zaccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3715
subroutine zaccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:3547
subroutine saccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4713
integer function, public accel_kernel_block_size(kernel)
Definition: accel.F90:1217
subroutine saccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4767
subroutine zaccel_write_buffer_single(this, data, async)
Definition: accel.F90:3133
subroutine daccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:2558
subroutine iaccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:7234
subroutine zaccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:3606
subroutine laccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:8190
subroutine iaccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:6569
subroutine zaccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3511
subroutine accel_grid_size_array_i8(n, blocksizes, gridsizes)
Computes the grid size for a given problem size and block size (64-bit version).
Definition: accel.F90:776
subroutine laccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:7678
subroutine zaccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3637
subroutine iaccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:6338
subroutine laccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:7515
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:990
subroutine saccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5085
subroutine daccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2212
subroutine iaccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:6496
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
Definition: accel.F90:1864
subroutine iaccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:6388
subroutine zaccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3286
subroutine iaccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:6970
subroutine saccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:5001
subroutine zaccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:3382
subroutine, public accel_get_stream(stream_number)
Definition: accel.F90:1929
subroutine accel_create_buffer_4(this, flags, type, size, set_zero, async)
Definition: accel.F90:921
subroutine caccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:6053
subroutine zaccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:3764
subroutine iaccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:6466
integer(int64) pure function, public accel_global_memory_size()
Definition: accel.F90:1883
subroutine caccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6093
subroutine saccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4739
subroutine saccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:4658
subroutine daccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2613
subroutine laccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:7387
subroutine caccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:5418
subroutine saccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:4639
subroutine saccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4930
subroutine saccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:4434
subroutine daccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:2539
subroutine daccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:2157
subroutine zaccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:3949
subroutine daccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3034
subroutine caccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5390
subroutine iaccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:6789
subroutine daccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3010
integer(int64) function accel_padded_size_i8(nn)
Definition: accel.F90:891
subroutine accel_check_bandwidth()
Definition: accel.F90:1349
subroutine saccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4870
subroutine saccel_write_buffer_single(this, data, async)
Definition: accel.F90:4185
subroutine iaccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:6597
subroutine caccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:5290
subroutine daccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2864
subroutine caccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:5691
subroutine laccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:7748
subroutine caccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5581
subroutine daccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:2098
subroutine zaccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:3745
subroutine iaccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:7185
subroutine, public accel_finish()
Definition: accel.F90:1127
subroutine laccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:7646
subroutine accel_kernel_global_init()
Definition: accel.F90:1408
subroutine zaccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3818
subroutine daccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2667
subroutine accel_kernel_run_4(kernel, gridsizes, blocksizes, shared_memory_size)
Run a kernel with 4-byte integer sizes.
Definition: accel.F90:1199
subroutine zaccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:3186
subroutine caccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:5467
subroutine caccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:5448
subroutine iaccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:7117
subroutine laccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:8113
subroutine, public accel_copy_buffer(dest, src, type, nval, offset_dest, offset_src, async)
Copy nval elements of the given type between two device buffers.
Definition: accel.F90:1231
subroutine accel_grid_size_extend_dim_i4(n, pack_size, gridsizes, blocksizes, kernel)
Helper function to compute the grid for the kernels that relies on the batch size (pack_size) and the...
Definition: accel.F90:873
subroutine saccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:4198
subroutine accel_set_buffer_to(buffer, type, val, nval, offset, async)
Definition: accel.F90:1272
subroutine, public accel_move_buffer(buffer_from, buffer_to)
Move the buffer memory from the first buffer to the second.
Definition: accel.F90:1033
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
Definition: accel.F90:1059
subroutine saccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:4816
subroutine laccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:8150
subroutine iaccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:6438
subroutine daccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:2138
subroutine daccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:2697
subroutine caccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:5615
subroutine caccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5741
subroutine zaccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:3587
subroutine iaccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:6629
subroutine daccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2589
subroutine laccel_write_buffer_single(this, data, async)
Definition: accel.F90:7334
subroutine laccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:7916
subroutine daccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2941
subroutine accel_kernel_run_8(kernel, gridsizes, blocksizes, shared_memory_size)
Run a kernel with 8-byte integer sizes.
Definition: accel.F90:1161
subroutine iaccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:6935
subroutine zaccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:3344
subroutine zaccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:3363
subroutine saccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:4599
subroutine saccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4689
subroutine accel_set_buffer_to_zero_i8(buffer, type, nval, offset, async)
Definition: accel.F90:1313
subroutine zaccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:4033
logical pure function, public accel_buffer_is_allocated(this)
Definition: accel.F90:1119
integer, parameter, public accel_mem_read_write
Definition: accel.F90:185
subroutine caccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6137
subroutine accel_kernel_end(this)
Definition: accel.F90:1846
subroutine caccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:6016
subroutine laccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:7618
subroutine zaccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3477
subroutine zaccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3989
subroutine caccel_write_buffer_single(this, data, async)
Definition: accel.F90:5237
subroutine daccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2188
subroutine laccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:7984
type(c_ptr) function, public daccel_get_pointer_with_offset(buffer, offset)
Definition: accel.F90:1957
subroutine iaccel_write_buffer_single(this, data, async)
Definition: accel.F90:6285
subroutine iaccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:7141
integer pure function, public accel_max_size_per_dim(dim)
Definition: accel.F90:1898
subroutine zaccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3661
subroutine iaccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:6699
subroutine daccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:2499
subroutine iaccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:6916
subroutine accel_grid_size_array_i4(n, blocksizes, gridsizes)
Computes the grid size for a given problem size and block size (32-bit version).
Definition: accel.F90:796
subroutine iaccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:7030
subroutine caccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:5849
subroutine laccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:7461
subroutine laccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:7545
subroutine saccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5110
subroutine caccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5791
subroutine caccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5549
subroutine zaccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:3205
subroutine laccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:7946
subroutine saccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:4415
subroutine laccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:8259
subroutine iaccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:7163
subroutine zaccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3260
subroutine zaccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3417
subroutine saccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4497
subroutine saccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5134
subroutine daccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:2901
subroutine iaccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:6739
subroutine accel_grid_size_extend_dim_i8(n, pack_size, gridsizes, blocksizes, kernel)
Helper function to compute the grid for the kernels that relies on the batch size (pack_size) and the...
Definition: accel.F90:843
subroutine caccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6115
subroutine, public accel_kernel_build(this, file_name, kernel_name, flags)
Compile the program that contains a given kernel.
Definition: accel.F90:1822
subroutine, public accel_init(base_grp, namespace)
Definition: accel.F90:434
subroutine, public accel_end(namespace)
Definition: accel.F90:696
subroutine saccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:4797
subroutine laccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:7347
subroutine daccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2266
subroutine saccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4563
subroutine zaccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3687
subroutine, public accel_synchronize_all_streams()
Definition: accel.F90:1945
subroutine, public accel_set_stream(stream_number)
Definition: accel.F90:1910
subroutine laccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:7807
subroutine saccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:4835
subroutine iaccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:6998
subroutine saccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5063
subroutine iaccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:6813
subroutine laccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:8234
subroutine iaccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:6897
subroutine saccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5041
subroutine accel_grid_size_i8(n, blocksizes, gridsizes)
Computes the grid size for a given problem size and block size (64-bit version).
Definition: accel.F90:811
subroutine saccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4964
subroutine iaccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:6663
subroutine caccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5982
subroutine caccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6069
subroutine caccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6186
integer(int32) function accel_padded_size_i4(nn)
Definition: accel.F90:912
subroutine accel_set_buffer_to_zero_i4(buffer, type, nval, offset, async)
Definition: accel.F90:1329
subroutine daccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2463
subroutine laccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:7564
subroutine iaccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:7210
subroutine iaccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:6534
subroutine saccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4312
pure logical function, public accel_is_enabled()
Definition: accel.F90:414
subroutine zaccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3912
subroutine daccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:2296
subroutine saccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4288
subroutine iaccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:6412
subroutine daccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:2334
subroutine iaccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:6515
integer, parameter, public accel_mem_write_only
Definition: accel.F90:185
subroutine zaccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3445
subroutine daccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2770
subroutine caccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5364
subroutine laccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:7712
subroutine laccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:7965
subroutine daccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:2716
subroutine laccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:8047
subroutine daccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2238
subroutine daccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2985
subroutine iaccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:6758
subroutine laccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:7487
subroutine laccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:7406
subroutine daccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2429
subroutine laccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:7583
subroutine zaccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:4011
type(c_ptr) function, public zaccel_get_pointer_with_offset(buffer, offset)
Definition: accel.F90:1972
subroutine iaccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:7064
subroutine saccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5017
subroutine laccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:8019
subroutine daccel_write_buffer_single(this, data, async)
Definition: accel.F90:2085
subroutine daccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:2315
subroutine caccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:5868
subroutine saccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4338
subroutine zaccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:3146
subroutine caccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5521
subroutine accel_ensure_buffer_size_8(buffer, flags, type, required_size, set_zero, async)
Grow a buffer to at least required_size elements, reusing it if it is already big enough.
Definition: accel.F90:1095
type(accel_t), public accel
Definition: accel.F90:248
subroutine caccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5765
subroutine laccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:8212
subroutine iaccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:6867
subroutine caccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:5651
integer(int64) pure function, public accel_shared_memory_size()
Definition: accel.F90:1891
integer pure function, public accel_max_block_size()
Definition: accel.F90:1211
subroutine iaccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:7101
subroutine daccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:2735
subroutine iaccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:6839
subroutine iaccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:6298
subroutine zaccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:4082
subroutine saccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4529
subroutine accel_create_buffer_8(this, flags, type, size, set_zero, async)
Definition: accel.F90:934
subroutine laccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:7788
subroutine daccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2830
subroutine daccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2798
subroutine caccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:5250
subroutine accel_program_add(file_name, name)
Register a kernel for later retrieval.
Definition: accel.F90:1782
subroutine caccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5950
subroutine accel_set_kernel_arg_buffer(kernel, narg, buffer)
Definition: accel.F90:1139
subroutine accel_kernel_list()
The kernels each source provides.
Definition: accel.F90:1429
subroutine laccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:7888
subroutine zaccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:3783
subroutine zaccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3314
subroutine daccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2963
type(accel_kernel_t), pointer head
Definition: accel.F90:408
subroutine zaccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3846
subroutine, public alloc_cache_put(alloc_cache, size, loc, put)
subroutine, public alloc_cache_get(alloc_cache, size, found, loc)
integer(int64), parameter, public alloc_cache_any_size
real(real64), parameter, public m_zero
Definition: global.F90:200
System information (time, memory, sysname)
Definition: loct.F90:117
subroutine string_c_to_f(c_string, f_string)
convert a C string to a Fortran string
Definition: loct.F90:258
subroutine, public loct_sysname(name)
Definition: loct.F90:332
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
subroutine, public messages_new_line()
Definition: messages.F90:1089
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 messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
integer pure function, public types_get_size(this)
Definition: types.F90:157
type(type_t), parameter, public type_none
Definition: types.F90:135
This module defines the unit system, used for input and output.
type(unit_t), public unit_gigabytes
For larger amounts of data (natural code units are bytes)
type(unit_t), public unit_megabytes
For large amounts of data (natural code units are bytes)
type(unit_t), public unit_kilobytes
For small amounts of data (natural code units are bytes)
int true(void)