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, &
91
92 integer, public, parameter :: &
93 ACCEL_MEM_READ_ONLY = 0, &
96
98 ! Components are public by default
99#if defined(HAVE_CUDA)
100 type(c_ptr) :: cuda_context
101#else
102 integer :: dummy
103#endif
104 end type accel_context_t
105
106 type accel_device_t
107 ! Components are public by default
108#if defined(HAVE_CUDA)
109 type(c_ptr) :: cuda_device
110#else
111 integer :: dummy
112#endif
113 end type accel_device_t
114
115 type accel_t
116 ! Components are public by default
117 type(accel_context_t) :: context
118 type(accel_device_t) :: device
119 type(c_ptr) :: cublas_handle
120 type(c_ptr) :: cuda_stream
121 type(c_ptr) :: program_map
122 integer :: max_block_size
123 integer(int64) :: shared_memory_size
124 integer(int64) :: global_memory_size
125 logical :: enabled
126 logical :: allow_CPU_only
127 logical :: cuda_mpi
128 integer :: warp_size
129 integer(int64) :: initialize_buffers
130 character(len=32) :: debug_flag
131 integer(int64) :: max_block_dim(3)
132 integer(int64) :: max_grid_dim(3)
133 end type accel_t
134
135 type accel_mem_t
136 ! Components are public by default
137 type(c_ptr) :: mem
138 integer(c_size_t) :: size = 0
139 type(type_t) :: type
140 integer :: flags = 0
141 logical :: allocated = .false.
142 end type accel_mem_t
143
144 type accel_kernel_t
145 ! Components are public by default
146#ifdef HAVE_CUDA
147 type(c_ptr) :: cuda_kernel
148 type(c_ptr) :: arguments
149#endif
150 logical :: initialized = .false.
151 type(accel_kernel_t), pointer :: next
152 integer :: arg_count
153 character(len=128) :: kernel_name
154 end type accel_kernel_t
155
156 type(accel_t), public :: accel
157
158 ! Global variables defined on device
159 type(accel_mem_t), public, save :: zM_0_buffer, zM_1_buffer
160 type(accel_mem_t), public, save :: dM_0_buffer, dM_1_buffer
161
162 ! the kernels
163 type(accel_kernel_t), public, target, save :: kernel_vpsi
164 type(accel_kernel_t), public, target, save :: kernel_vpsi_complex
165 type(accel_kernel_t), public, target, save :: kernel_vpsi_spinors
166 type(accel_kernel_t), public, target, save :: kernel_vpsi_spinors_complex
167 type(accel_kernel_t), public, target, save :: kernel_daxpy
168 type(accel_kernel_t), public, target, save :: kernel_zaxpy
169 type(accel_kernel_t), public, target, save :: kernel_copy
170 type(accel_kernel_t), public, target, save :: kernel_copy_complex_to_real
171 type(accel_kernel_t), public, target, save :: kernel_copy_real_to_complex
172 type(accel_kernel_t), public, target, save :: dpack
173 type(accel_kernel_t), public, target, save :: zpack
174 type(accel_kernel_t), public, target, save :: dunpack
175 type(accel_kernel_t), public, target, save :: zunpack
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
185
186 interface accel_grid_size
188 end interface accel_grid_size
189
193
194 interface accel_padded_size
196 end interface accel_padded_size
198 interface accel_create_buffer
200 end interface accel_create_buffer
202 interface accel_kernel_run
203 module procedure accel_kernel_run_4, accel_kernel_run_8
204 end interface accel_kernel_run
205
208 end interface accel_set_buffer_to_zero
209
233 end interface accel_write_buffer
250 end interface accel_read_buffer
252 interface accel_set_kernel_arg
253 module procedure &
277 module procedure &
283
285 module procedure &
291
292 integer :: buffer_alloc_count
293 integer(int64) :: allocated_mem
294 type(accel_kernel_t), pointer :: head
295 type(alloc_cache_t) :: memcache
296
297contains
298
299 pure logical function accel_is_enabled() result(enabled)
300#ifdef HAVE_ACCEL
301 enabled = accel%enabled
302#else
303 enabled = .false.
304#endif
305 end function accel_is_enabled
306
307 ! ------------------------------------------
308
309 pure logical function accel_allow_cpu_only() result(allow)
310#ifdef HAVE_ACCEL
311 allow = accel%allow_CPU_only
312#else
313 allow = .true.
314#endif
315 end function accel_allow_cpu_only
316
317 ! ------------------------------------------
318
319 subroutine accel_init(base_grp, namespace)
320 type(mpi_grp_t), intent(inout) :: base_grp
321 type(namespace_t), intent(in) :: namespace
322
323 logical :: disable, default, run_benchmark
324 integer :: idevice
325#ifdef HAVE_CUDA
326 integer :: dim
327#ifdef HAVE_MPI
328 character(len=256) :: sys_name
329#endif
330#endif
331
332 push_sub(accel_init)
333
334 buffer_alloc_count = 0
335
336 !%Variable DisableAccel
337 !%Type logical
338 !%Default yes
339 !%Section Execution::Accel
340 !%Description
341 !% If Octopus was compiled with CUDA support, it will
342 !% try to initialize and use an accelerator device. By setting this
343 !% variable to <tt>yes</tt> you force Octopus not to use an accelerator even it is available.
344 !%End
345 call messages_obsolete_variable(namespace, 'DisableOpenCL', 'DisableAccel')
346#ifdef HAVE_ACCEL
347 default = .false.
348#else
349 default = .true.
350#endif
351 call parse_variable(namespace, 'DisableAccel', default, disable)
352 accel%enabled = .not. disable
353
354#ifndef HAVE_ACCEL
355 if (accel%enabled) then
356 message(1) = 'Octopus was compiled without Cuda support.'
357 call messages_fatal(1)
358 end if
359#endif
360
361 if (.not. accel_is_enabled()) then
362 pop_sub(accel_init)
363 return
364 end if
365
366 call messages_obsolete_variable(namespace, 'AccelPlatform')
367 call messages_obsolete_variable(namespace, 'OpenCLPlatform', 'AccelPlatform')
368
369 !%Variable AccelDevice
370 !%Type integer
371 !%Default 0
372 !%Section Execution::Accel
373 !%Description
374 !% This variable selects the GPU that Octopus will use. You can specify a
375 !% numerical id to select a specific device.
376 !%
377 !% In case of MPI enabled runs devices are distributed in a round robin fashion,
378 !% starting at this value.
379 !%End
380 call parse_variable(namespace, 'AccelDevice', 0, idevice)
381
382 call messages_obsolete_variable(namespace, 'OpenCLDevice', 'AccelDevice')
383
384 if (idevice < 0) then
385 call messages_write('Invalid AccelDevice')
386 call messages_fatal()
387 end if
389 call messages_print_with_emphasis(msg="GPU acceleration", namespace=namespace)
391#ifdef HAVE_CUDA
392 if (idevice<0) idevice = 0
393 call cuda_init(accel%context%cuda_context, accel%device%cuda_device, accel%cuda_stream, &
394 idevice, base_grp%rank)
395#ifdef HAVE_MPI
396 call loct_sysname(sys_name)
397 write(message(1), '(A,I5,A,I5,2A)') "Rank ", base_grp%rank, " uses device number ", idevice, &
398 " on ", trim(sys_name)
399 call messages_info(1, all_nodes = .true.)
400#endif
401
402 call cublas_init(accel%cublas_handle, accel%cuda_stream)
403#endif
405
406 ! Get some device information that we will need later
407#ifdef HAVE_CUDA
408 call cuda_device_total_memory(accel%device%cuda_device, accel%global_memory_size)
409 call cuda_device_shared_memory(accel%device%cuda_device, accel%shared_memory_size)
410 call cuda_device_max_threads_per_block(accel%device%cuda_device, accel%max_block_size)
411 call cuda_device_get_warpsize(accel%device%cuda_device, accel%warp_size)
412 call cuda_device_max_block_dim_x(accel%device%cuda_device, dim)
413 accel%max_block_dim(1) = int(dim, int64)
414 call cuda_device_max_block_dim_y(accel%device%cuda_device, dim)
415 accel%max_block_dim(2) = int(dim, int64)
416 call cuda_device_max_block_dim_z(accel%device%cuda_device, dim)
417 accel%max_block_dim(3) = int(dim, int64)
418 call cuda_device_max_grid_dim_x(accel%device%cuda_device, dim)
419 accel%max_grid_dim(1) = int(dim, int64)
420 call cuda_device_max_grid_dim_y(accel%device%cuda_device, dim)
421 accel%max_grid_dim(2) = int(dim, int64)
422 call cuda_device_max_grid_dim_z(accel%device%cuda_device, dim)
423 accel%max_grid_dim(3) = int(dim, int64)
424#endif
425
426 if (base_grp%is_root()) call device_info()
427
428 ! initialize the cache used to speed up allocations
429 call alloc_cache_init(memcache, nint(0.25_real64*accel%global_memory_size, int64))
430
431 ! now initialize the kernels
433
434#if defined(HAVE_HIP)
435 accel%debug_flag = "-g"
436#elif defined(HAVE_CUDA)
437 accel%debug_flag = "-lineinfo"
438#endif
439
440 call accel_kernel_start_call(kernel_vpsi, 'vpsi.cu', "vpsi<double>")
441 call accel_kernel_start_call(kernel_vpsi_complex, 'vpsi.cu', "vpsi_complex<double>")
442 call accel_kernel_start_call(kernel_vpsi_spinors, 'vpsi.cu', "vpsi_spinors<double>")
443 call accel_kernel_start_call(kernel_vpsi_spinors_complex, 'vpsi.cu', "vpsi_spinors_complex<double>")
444 call accel_kernel_start_call(kernel_daxpy, 'axpy.cu', "axpy<double>")
445 call accel_kernel_start_call(kernel_zaxpy, 'axpy.cu', "axpy<complex<double>>")
446 call accel_kernel_start_call(dpack, 'pack.cu', "pack<double>")
447 call accel_kernel_start_call(zpack, 'pack.cu', "pack<complex<double>>")
448 call accel_kernel_start_call(dunpack, 'pack.cu', "unpack<double>")
449 call accel_kernel_start_call(zunpack, 'pack.cu', "unpack<complex<double>>")
450 call accel_kernel_start_call(kernel_copy, 'copy.cu', "copy<double>")
451 call accel_kernel_start_call(kernel_copy_complex_to_real, 'copy.cu', "copy_complex_to_real<double>")
452 call accel_kernel_start_call(kernel_copy_real_to_complex, 'copy.cu', "copy_real_to_complex<double>")
453 call accel_kernel_start_call(kernel_ghost_reorder, 'ghost.cu', "ghost_reorder<double>")
454 call accel_kernel_start_call(kernel_density_real, 'density.cu', "density<double, double>")
455 call accel_kernel_start_call(kernel_density_complex, 'density.cu', "density<double, complex<double>>")
456 call accel_kernel_start_call(kernel_density_spinors, 'density.cu', "density_spinors<double>")
457 call accel_kernel_start_call(kernel_phase, 'phase.cu', "phase<double>")
458 call accel_kernel_start_call(zkernel_dot_matrix_spinors, 'mesh_batch.cu', "zdot_matrix_spinors<double>")
459
460
461 call accel_kernel_start_call(dzmul_batch, 'mul.cu', 'zmul_batch<double, double>')
462 call accel_kernel_start_call(zzmul_batch, 'mul.cu', 'zmul_batch<double, complex<double>>')
463
464 ! Define global buffers
465 if(.not. accel_buffer_is_allocated(zm_0_buffer)) then
466 call accel_create_buffer(zm_0_buffer, accel_mem_read_only, type_cmplx, 1)
467 call accel_write_buffer(zm_0_buffer, m_z0)
468 end if
469 if(.not. accel_buffer_is_allocated(zm_1_buffer)) then
470 call accel_create_buffer(zm_1_buffer, accel_mem_read_only, type_cmplx, 1)
471 call accel_write_buffer(zm_1_buffer, m_z1)
472 end if
473 if(.not. accel_buffer_is_allocated(dm_0_buffer)) then
474 call accel_create_buffer(dm_0_buffer, accel_mem_read_only, type_float, 1)
475 call accel_write_buffer(dm_0_buffer, m_zero)
476 end if
477 if(.not. accel_buffer_is_allocated(dm_1_buffer)) then
478 call accel_create_buffer(dm_1_buffer, accel_mem_read_only, type_float, 1)
479 call accel_write_buffer(dm_1_buffer, m_one)
480 end if
481
482
483 !%Variable AccelBenchmark
484 !%Type logical
485 !%Default no
486 !%Section Execution::Accel
487 !%Description
488 !% If this variable is set to yes, Octopus will run some
489 !% routines to benchmark the performance of the accelerator device.
490 !%End
491 call parse_variable(namespace, 'AccelBenchmark', .false., run_benchmark)
492
493 call messages_obsolete_variable(namespace, 'OpenCLBenchmark', 'AccelBenchmark')
494
495 if (run_benchmark) then
497 end if
498
499 !%Variable GPUAwareMPI
500 !%Type logical
501 !%Section Execution::Accel
502 !%Description
503 !% If Octopus was compiled with GPU support and MPI support and if the MPI
504 !% implementation is GPU-aware (i.e., it supports communication using device pointers),
505 !% this switch can be set to true to use the GPU-aware MPI features. The advantage
506 !% of this approach is that it can do, e.g., peer-to-peer copies between devices without
507 !% going through the host memory.
508 !% The default is false, except when the configure switch --enable-cudampi is set, in which
509 !% case this variable is set to true.
510 !%End
511#ifdef HAVE_CUDA_MPI
512 default = .true.
513#else
514 default = .false.
515#endif
516 call parse_variable(namespace, 'GPUAwareMPI', default, accel%cuda_mpi)
517 if (accel%cuda_mpi) then
518#ifndef HAVE_CUDA_MPI
519 call messages_write("Warning: trying to use GPU-aware MPI, but we have not detected support in the linked MPI library.")
520 call messages_warning()
521#endif
522 call messages_write("Using GPU-aware MPI.")
523 call messages_info()
524 end if
525
526
527 !%Variable AllowCPUonly
528 !%Type logical
529 !%Section Execution::Accel
530 !%Description
531 !% In order to prevent waste of resources, the code will normally stop when the GPU is disabled due to
532 !% incomplete implementations or incompatibilities. AllowCPUonly = yes overrides this and allows the
533 !% code execution also in these cases.
534 !%End
535#if defined (HAVE_ACCEL)
536 default = .false.
537#else
538 default = .true.
539#endif
540 call parse_variable(namespace, 'AllowCPUonly', default, accel%allow_CPU_only)
541
542
543 !%Variable InitializeGPUBuffers
544 !%Type integer
545 !%Default no
546 !%Section Execution::Accel
547 !%Description
548 !% Initialize new GPU buffers to zero on creation (use only for debugging, as it has a performance impact!).
549 !%Option no 0
550 !% Do not initialize GPU buffers.
551 !%Option yes 1
552 !% Initialize GPU buffers to zero.
553 !%Option nan 2
554 !% Initialize GPU buffers to nan.
555 !%End
556 call parse_variable(namespace, 'InitializeGPUBuffers', option__initializegpubuffers__no, accel%initialize_buffers)
557 if (.not. varinfo_valid_option('InitializeGPUBuffers', accel%initialize_buffers)) then
558 call messages_input_error(namespace, 'InitializeGPUBuffers')
559 end if
560
561
562 call messages_print_with_emphasis(namespace=namespace)
563
564 pop_sub(accel_init)
565
566 contains
567
568 subroutine device_info()
569#ifdef HAVE_CUDA
570 integer :: version
571 character(kind=c_char) :: cval_str(257)
572#endif
573 integer :: major, minor
574 character(len=256) :: val_str
575
576 push_sub(accel_init.device_info)
577
578 call messages_new_line()
579 call messages_write('Selected device:')
580 call messages_new_line()
581
582#ifdef HAVE_CUDA
583#ifdef __HIP_PLATFORM_AMD__
584 call messages_write(' Framework : ROCm')
585#else
586 call messages_write(' Framework : CUDA')
587#endif
588#endif
589 call messages_info()
590
591#ifdef HAVE_CUDA
592 call messages_write(' Device type : GPU', new_line = .true.)
593#ifdef __HIP_PLATFORM_AMD__
594 call messages_write(' Device vendor : AMD Corporation', new_line = .true.)
595#else
596 call messages_write(' Device vendor : NVIDIA Corporation', new_line = .true.)
597#endif
598#endif
599
600#ifdef HAVE_CUDA
601 cval_str = c_null_char
602 call cuda_device_name(accel%device%cuda_device, cval_str)
603 call string_c_to_f(cval_str, val_str)
604#endif
605 call messages_write(' Device name : '//trim(val_str))
606 call messages_new_line()
607
608#ifdef HAVE_CUDA
609 call cuda_device_capability(accel%device%cuda_device, major, minor)
610#endif
611 call messages_write(' Cuda capabilities :')
612 call messages_write(major, fmt = '(i2)')
613 call messages_write('.')
614 call messages_write(minor, fmt = '(i1)')
615 call messages_new_line()
616
617 ! VERSION
618#ifdef HAVE_CUDA
619 call cuda_driver_version(version)
620 call messages_write(' Driver version : ')
621 call messages_write(version)
622#endif
623 call messages_new_line()
624
625
626 call messages_write(' Device memory :')
627 call messages_write(accel%global_memory_size, units=unit_megabytes)
628 call messages_new_line()
629
630 call messages_write(' Shared memory :')
631 call messages_write(accel%shared_memory_size, units=unit_kilobytes)
632 call messages_new_line()
633
634 call messages_write(' Max. block size :')
635 call messages_write(accel%max_block_size)
636 call messages_new_line()
637
638 call messages_info()
639
640 pop_sub(accel_init.device_info)
641 end subroutine device_info
642
643 end subroutine accel_init
644
645 ! ------------------------------------------
646 subroutine accel_end(namespace)
647 type(namespace_t), intent(in) :: namespace
648
649 integer(int64) :: hits, misses
650 real(real64) :: volume_hits, volume_misses
651 logical :: found
652 type(accel_mem_t) :: tmp
653
654 push_sub(accel_end)
655
656 if (accel_is_enabled()) then
657
658 ! Release global buffers
659 call accel_free_buffer(zm_0_buffer)
660 call accel_free_buffer(zm_1_buffer)
661 call accel_free_buffer(dm_0_buffer)
662 call accel_free_buffer(dm_1_buffer)
663
664 do
665 call alloc_cache_get(memcache, alloc_cache_any_size, found, tmp%mem)
666 if (.not. found) exit
667
668#ifdef HAVE_CUDA
669 call cuda_mem_free(tmp%mem)
670#endif
671 end do
672
673 call alloc_cache_end(memcache, hits, misses, volume_hits, volume_misses)
674
675 call messages_print_with_emphasis(msg="Acceleration-device allocation cache", namespace=namespace)
676
677 call messages_new_line()
678 call messages_write(' Number of allocations =')
679 call messages_write(hits + misses, new_line = .true.)
680 call messages_write(' Volume of allocations =')
681 call messages_write(volume_hits + volume_misses, fmt = 'f18.1', units = unit_gigabytes, align_left = .true., &
682 new_line = .true.)
683 call messages_write(' Hit ratio =')
684 if (hits + misses > 0) then
685 call messages_write(hits/real(hits + misses, real64)*100, fmt='(f6.1)', align_left = .true.)
686 else
687 call messages_write(m_zero, fmt='(f6.1)', align_left = .true.)
688 end if
689 call messages_write('%', new_line = .true.)
690 call messages_write(' Volume hit ratio =')
691 if (volume_hits + volume_misses > 0) then
692 call messages_write(volume_hits/(volume_hits + volume_misses)*100, fmt='(f6.1)', align_left = .true.)
693 else
694 call messages_write(m_zero, fmt='(f6.1)', align_left = .true.)
695 end if
696 call messages_write('%')
697 call messages_new_line()
698 call messages_info()
699
700 call messages_print_with_emphasis(namespace=namespace)
701 end if
702
704
705 if (accel_is_enabled()) then
706#ifdef HAVE_CUDA
707 call cublas_end(accel%cublas_handle)
708 if (.not. accel%cuda_mpi) then ! CUDA aware MPI finalize will do the cleanup
709 call cuda_end(accel%context%cuda_context, accel%device%cuda_device)
710 end if
711#endif
712
713 if (buffer_alloc_count /= 0) then
714 call messages_write('Accel:')
715 call messages_write(real(allocated_mem, real64) , fmt = 'f12.1', units = unit_megabytes, align_left = .true.)
716 call messages_write(' in ')
717 call messages_write(buffer_alloc_count)
718 call messages_write(' buffers were not deallocated.')
719 call messages_fatal()
720 end if
721
722 end if
723
724 pop_sub(accel_end)
725 end subroutine accel_end
726
727 ! ------------------------------------------
728
730 subroutine accel_grid_size_array_i8(n, blocksizes, gridsizes)
731 integer(int64), intent(in) :: n(:)
732 integer(int64), intent(in) :: blocksizes(:)
733 integer(int64), intent(out) :: gridsizes(:)
734
735 integer :: dim, i
736
737 dim = ubound(n, dim=1)
738 assert(dim == ubound(blocksizes, dim=1))
739 assert(dim == ubound(gridsizes, dim=1))
740
741 do i = 1, dim
742 gridsizes(i) = (n(i) + blocksizes(i) - 1_int64) / blocksizes(i)
743 gridsizes(i) = min(gridsizes(i), accel%max_grid_dim(i))
744 end do
745 end subroutine accel_grid_size_array_i8
746
747 ! ------------------------------------------
748
750 subroutine accel_grid_size_array_i4(n, blocksizes, gridsizes)
751 integer, intent(in) :: n(:)
752 integer, intent(in) :: blocksizes(:)
753 integer, intent(out) :: gridsizes(:)
754
755 integer(int64) :: gridsizes64(size(gridsizes))
756
757 call accel_grid_size_array_i8(int(n(:), int64), int(blocksizes(:), int64), gridsizes64)
758
759 gridsizes = int(gridsizes64, int32)
760 end subroutine accel_grid_size_array_i4
761
762 ! ------------------------------------------
763
765 subroutine accel_grid_size_i8(n, blocksizes, gridsizes)
766 integer(int64), intent(in) :: n
767 integer(int64), intent(in) :: blocksizes
768 integer(int64), intent(out) :: gridsizes
769
770 integer(int64) :: temp(1)
772 call accel_grid_size_array_i8( (/n/), (/blocksizes/), temp)
773
774 gridsizes = temp(1)
775 end subroutine accel_grid_size_i8
776
777 ! ------------------------------------------
778
780 subroutine accel_grid_size_i4(n, blocksizes, gridsizes)
781 integer, intent(in) :: n
782 integer, intent(in) :: blocksizes
783 integer, intent(out) :: gridsizes
784
785 integer(int64) :: temp(1)
786
787 call accel_grid_size_array_i8(int((/n/), int64), int((/blocksizes/), int64), temp)
788
789 gridsizes = int(temp(1), int32)
790 end subroutine accel_grid_size_i4
792! ------------------------------------------
793
797 subroutine accel_grid_size_extend_dim_i8(n, pack_size, gridsizes, blocksizes, kernel)
798 integer(int64), intent(in) :: n
799 integer(int64), intent(in) :: pack_size
800 integer(int64), dimension(3), intent(out) :: gridsizes
801 integer(int64), dimension(3), intent(out) :: blocksizes
802 type(accel_kernel_t), optional, intent(inout) :: kernel
803
804 integer(int64) :: bsize, dim2, dim3
805 integer(int64), dimension(3) :: nn
807 if(present(kernel)) then
808 bsize = accel_kernel_block_size(kernel)/pack_size
809 else
810 bsize = accel_max_block_size()/pack_size
811 end if
812
813 dim3 = n/(accel_max_size_per_dim(2)*bsize) + 1
814 dim2 = min(accel_max_size_per_dim(2)*bsize, pad(n, bsize))
815
816 nn = (/pack_size, dim2, dim3/)
817 blocksizes = (/pack_size, bsize, 1_int64/)
818
819 call accel_grid_size(nn, blocksizes, gridsizes)
820 end subroutine accel_grid_size_extend_dim_i8
822 ! ------------------------------------------
823
827 subroutine accel_grid_size_extend_dim_i4(n, pack_size, gridsizes, blocksizes, kernel)
828 integer, intent(in) :: n
829 integer, intent(in) :: pack_size
830 integer, dimension(3), intent(out) :: gridsizes
831 integer, dimension(3), intent(out) :: blocksizes
832 type(accel_kernel_t), optional, intent(inout) :: kernel
833
834 integer(int64) :: gridsizes64(3), blocksizes64(3)
835
836 call accel_grid_size_extend_dim_i8(int(n, int64), int(pack_size, int64), &
837 gridsizes64, blocksizes64, kernel=kernel)
839 gridsizes = int(gridsizes64, int32)
840 blocksizes = int(blocksizes64, int32)
841 end subroutine accel_grid_size_extend_dim_i4
842
843 ! ------------------------------------------
844
845 integer(int64) function accel_padded_size_i8(nn) result(psize)
846 integer(int64), intent(in) :: nn
847
848 integer(int64) :: modnn, bsize
849
850 psize = nn
851
852 if (accel_is_enabled()) then
853
854 bsize = accel_max_block_size()
855
856 psize = nn
857 modnn = mod(nn, bsize)
858 if (modnn /= 0) psize = psize + bsize - modnn
859
860 end if
861
862 end function accel_padded_size_i8
863
864 ! ------------------------------------------
865
866 integer(int32) function accel_padded_size_i4(nn) result(psize)
867 integer(int32), intent(in) :: nn
869 psize = int(accel_padded_size_i8(int(nn, int64)), int32)
870
871 end function accel_padded_size_i4
872
873 ! ------------------------------------------
874
875 subroutine accel_create_buffer_4(this, flags, type, size, set_zero, async)
876 type(accel_mem_t), intent(inout) :: this
877 integer, intent(in) :: flags
878 type(type_t), intent(in) :: type
879 integer, intent(in) :: size
880 logical, optional, intent(in) :: set_zero
881 logical, optional, intent(in) :: async
882
883 call accel_create_buffer_8(this, flags, type, int(size, int64), set_zero, async)
884 end subroutine accel_create_buffer_4
885
886 ! ------------------------------------------
887
888 subroutine accel_create_buffer_8(this, flags, type, size, set_zero, async)
889 type(accel_mem_t), intent(inout) :: this
890 integer, intent(in) :: flags
891 type(type_t), intent(in) :: type
892 integer(int64), intent(in) :: size
893 logical, optional, intent(in) :: set_zero
894 logical, optional, intent(in) :: async
895
896 integer(int64) :: fsize
897 logical :: found
898 integer(int64) :: initialize_buffers
899
900 push_sub(accel_create_buffer_8)
901
902 this%type = type
903 this%size = size
904 this%flags = flags
905 fsize = int(size, int64)*types_get_size(type)
906 this%allocated = .true.
908 if (fsize > 0) then
909
910 call alloc_cache_get(memcache, fsize, found, this%mem)
911
912 if (.not. found) then
913#ifdef HAVE_CUDA
914 if(optional_default(async, .false.)) then
915 call cuda_mem_alloc_async(this%mem, fsize)
916 else
917 call cuda_mem_alloc(this%mem, fsize)
918 end if
919#endif
920 end if
921
922 buffer_alloc_count = buffer_alloc_count + 1
923 allocated_mem = allocated_mem + fsize
924
925 end if
926
927 if (present(set_zero)) then
928 initialize_buffers = merge(option__initializegpubuffers__yes, option__initializegpubuffers__no, set_zero)
929 else
930 initialize_buffers = accel%initialize_buffers
931 end if
932 select case (initialize_buffers)
933 case (option__initializegpubuffers__yes)
934 call accel_set_buffer_to(this, type, int(z'00', int8), size, async=async)
935 case (option__initializegpubuffers__nan)
936 call accel_set_buffer_to(this, type, int(z'FF', int8), size, async=async)
937 end select
938
939 pop_sub(accel_create_buffer_8)
940 end subroutine accel_create_buffer_8
941
942 ! ------------------------------------------
943
944 subroutine accel_free_buffer(this, async)
945 type(accel_mem_t), intent(inout) :: this
946 logical, optional, intent(in) :: async
947
948 logical :: put
949 integer(int64) :: fsize
950
951 push_sub(accel_free_buffer)
952
953 if (this%size > 0) then
954
955 fsize = int(this%size, int64)*types_get_size(this%type)
956
957 call alloc_cache_put(memcache, fsize, this%mem, put)
958
959 if (.not. put) then
960#ifdef HAVE_CUDA
961 if (optional_default(async, .false.)) then
962 call cuda_mem_free_async(this%mem)
963 else
964 call cuda_mem_free(this%mem)
965 end if
966#endif
967 end if
968
969 buffer_alloc_count = buffer_alloc_count - 1
970 allocated_mem = allocated_mem + fsize
971
972 end if
973
974 this%size = 0
975 this%flags = 0
976
977 this%allocated = .false.
978
979 pop_sub(accel_free_buffer)
980 end subroutine accel_free_buffer
981
982 ! ------------------------------------------
983
987 subroutine accel_move_buffer(buffer_from, buffer_to)
988 type(accel_mem_t), intent(inout) :: buffer_from
989 type(accel_mem_t), intent(inout) :: buffer_to
990
991 push_sub(accel_move_buffer)
992
993 ! Can not move an allocated buffer, the destination buffer should be empty
994 assert(.not. accel_buffer_is_allocated(buffer_to))
995
996 buffer_to%mem = buffer_from%mem
997 buffer_to%size = buffer_from%size
998 buffer_to%type = buffer_from%type
999 buffer_to%flags = buffer_from%flags
1000 buffer_to%allocated = buffer_from%allocated
1001
1002 call accel_detach_buffer(buffer_from)
1003
1004 pop_sub(accel_move_buffer)
1005 end subroutine accel_move_buffer
1006
1007 ! ------------------------------------------
1008
1013 subroutine accel_detach_buffer(this)
1014 type(accel_mem_t), intent(inout) :: this
1015
1016 push_sub(accel_detach_buffer)
1017
1018 this%mem = c_null_ptr
1019 this%size = 0
1020 this%type = type_none
1021 this%flags = 0
1022 this%allocated = .false.
1023
1024 pop_sub(accel_detach_buffer)
1025 end subroutine accel_detach_buffer
1026
1027 ! ------------------------------------------------------
1029 ! Check if the temporary buffers are the right size, if not reallocate them
1030 subroutine accel_ensure_buffer_size(buffer, flags, type, required_size, set_zero, async)
1031 type(accel_mem_t), intent(inout) :: buffer
1032 integer, intent(in) :: flags
1033 type(type_t), intent(in) :: type
1034 integer, intent(in) :: required_size
1035 logical, intent(in) :: set_zero
1036 logical, optional, intent(in) :: async
1037
1038 push_sub(accel_ensure_buffer_size)
1039
1040
1041 if (accel_buffer_is_allocated(buffer) .and. buffer%size < required_size) then
1042 call accel_free_buffer(buffer, async=optional_default(async, .false.))
1043 end if
1044
1045 if (.not. accel_buffer_is_allocated(buffer)) then
1046 call accel_create_buffer(buffer, flags, type, required_size, set_zero=set_zero, async=optional_default(async, .false.))
1047 end if
1048
1050 end subroutine accel_ensure_buffer_size
1051
1052 ! ------------------------------------------
1053
1054 logical pure function accel_buffer_is_allocated(this) result(allocated)
1055 type(accel_mem_t), intent(in) :: this
1056
1057 allocated = this%allocated
1058 end function accel_buffer_is_allocated
1059
1060 ! -----------------------------------------
1061
1062 subroutine accel_finish()
1063 ! no push_sub, called too frequently
1064
1065 if (accel_is_enabled()) then
1066#ifdef HAVE_CUDA
1068#endif
1069 end if
1070 end subroutine accel_finish
1072 ! ------------------------------------------
1073
1074 subroutine accel_set_kernel_arg_buffer(kernel, narg, buffer)
1075 type(accel_kernel_t), intent(inout) :: kernel
1076 integer, intent(in) :: narg
1077 type(accel_mem_t), intent(in) :: buffer
1078
1079 assert(accel_buffer_is_allocated(buffer))
1080
1081 ! no push_sub, called too frequently
1082#ifdef HAVE_CUDA
1083 call cuda_kernel_set_arg_buffer(kernel%arguments, buffer%mem, narg)
1084#endif
1085
1086 end subroutine accel_set_kernel_arg_buffer
1087
1088 ! ------------------------------------------
1089
1096 subroutine accel_kernel_run_8(kernel, gridsizes, blocksizes, shared_memory_size)
1097 type(accel_kernel_t), intent(inout) :: kernel
1098 integer(int64), intent(in) :: gridsizes(:)
1099 integer(int64), intent(in) :: blocksizes(:)
1100 integer(int64), optional, intent(in) :: shared_memory_size
1101
1102 integer :: dim
1103 integer(int64) :: gsizes(1:3)
1104 integer(int64) :: bsizes(1:3)
1105
1106 ! no push_sub, called too frequently
1107
1108 ! CUDA needs all dimensions
1109 gsizes = 1
1110 bsizes = 1
1111
1112 dim = ubound(gridsizes, dim=1)
1113
1114 assert(dim == ubound(blocksizes, dim=1))
1116 ! if one size is zero, there is nothing to do
1117 if (any(gridsizes == 0)) return
1118
1119 assert(all(blocksizes > 0))
1120
1121 gsizes(1:dim) = gridsizes(1:dim)
1122 bsizes(1:dim) = blocksizes(1:dim)
1123
1124#ifdef HAVE_CUDA
1125 ! Maximum dimension of a block
1126 if (any(bsizes(1:3) > accel%max_block_dim(1:3))) then
1127 message(1) = "Maximum dimension of a block too large in kernel "//trim(kernel%kernel_name)
1128 message(2) = "The following conditions should be fulfilled:"
1129 write(message(3), "(A, I8, A, I8)") "Dim 1: ", bsizes(1), " <= ", accel%max_block_dim(1)
1130 write(message(4), "(A, I8, A, I8)") "Dim 2: ", bsizes(2), " <= ", accel%max_block_dim(2)
1131 write(message(5), "(A, I8, A, I8)") "Dim 3: ", bsizes(3), " <= ", accel%max_block_dim(3)
1132 message(6) = "This is an internal error, please contact the developers."
1133 call messages_fatal(6)
1134 end if
1135
1136
1137 ! Maximum number of threads per block
1138 if (product(bsizes) > accel_max_block_size()) then
1139 message(1) = "Maximum number of threads per block too large in kernel "//trim(kernel%kernel_name)
1140 message(2) = "The following condition should be fulfilled:"
1141 write(message(3), "(I8, A, I8)") product(bsizes), " <= ", accel_max_block_size()
1142 message(4) = "This is an internal error, please contact the developers."
1143 call messages_fatal(4)
1144 end if
1145
1146 ! Maximum dimensions of the grid of thread block
1147 if (any(gsizes(1:3) > accel%max_grid_dim(1:3))) then
1148 message(1) = "Maximum dimension of grid too large in kernel "//trim(kernel%kernel_name)
1149 message(2) = "The following conditions should be fulfilled:"
1150 write(message(3), "(A, I8, A, I10)") "Dim 1: ", gsizes(1), " <= ", accel%max_grid_dim(1)
1151 write(message(4), "(A, I8, A, I10)") "Dim 2: ", gsizes(2), " <= ", accel%max_grid_dim(2)
1152 write(message(5), "(A, I8, A, I10)") "Dim 3: ", gsizes(3), " <= ", accel%max_grid_dim(3)
1153 message(6) = "This is an internal error, please contact the developers."
1154 call messages_fatal(6)
1155 end if
1156
1157 if(present(shared_memory_size)) then
1158
1159 if (shared_memory_size > accel%shared_memory_size) then
1160 message(1) = "Shared memory too large in kernel "//trim(kernel%kernel_name)
1161 message(2) = "The following condition should be fulfilled:"
1162 message(3) = "Requested shared memory <= Available shared memory"
1163 write(message(4), '(a,f12.6,a)') "Requested shared memory: ", real(shared_memory_size, real64) /1024.0, " Kb"
1164 write(message(5), '(a,f12.6,a)') "Available shared memory: ", real(accel%shared_memory_size, real64) /1024.0, " Kb"
1165 message(6) = "This is an internal error, please contact the developers."
1166 call messages_fatal(6)
1167 else if (shared_memory_size <= 0) then
1168 message(1) = "Invalid shared memory size in kernel "//trim(kernel%kernel_name)
1169 write(message(2), '(a,f12.6,a)') "Shared memory size requested: ", real(shared_memory_size, real64) /1024.0, " Kb"
1170 message(3) = "This is an internal error, please contact the developers."
1171 call messages_fatal(3)
1172 end if
1173 end if
1174
1175 call cuda_launch_kernel(kernel%cuda_kernel, gsizes(1), bsizes(1), &
1176 optional_default(shared_memory_size, 0_int64), kernel%arguments)
1177#endif
1178
1179 end subroutine accel_kernel_run_8
1180
1181 ! -----------------------------------------------
1182
1188
1189 subroutine accel_kernel_run_4(kernel, gridsizes, blocksizes, shared_memory_size)
1190 type(accel_kernel_t), intent(inout) :: kernel
1191 integer, intent(in) :: gridsizes(:)
1192 integer, intent(in) :: blocksizes(:)
1193 integer(int64), optional, intent(in) :: shared_memory_size
1194
1195 call accel_kernel_run_8(kernel, int(gridsizes, int64), int(blocksizes, int64), shared_memory_size)
1196
1197 end subroutine accel_kernel_run_4
1198
1199 ! -----------------------------------------------
1200
1201 integer pure function accel_max_block_size() result(max_block_size)
1202 max_block_size = accel%max_block_size
1203 end function accel_max_block_size
1204
1205 ! -----------------------------------------------
1206
1207 integer function accel_kernel_block_size(kernel) result(block_size)
1208 type(accel_kernel_t), intent(inout) :: kernel
1209
1210#ifdef HAVE_CUDA
1211 integer :: max_block_size
1212#endif
1213
1214 block_size = 0
1215
1216#ifdef HAVE_CUDA
1217 call cuda_kernel_max_threads_per_block(kernel%cuda_kernel, max_block_size)
1218 if (debug%info .and. max_block_size /= accel%max_block_size) then
1219 write(message(1), "(A, I5, A)") "A kernel can use only less threads per block (", max_block_size, ")", &
1220 "than available on the device (", accel%max_block_size, ")"
1221 call messages_info(1)
1222 end if
1223
1224 ! recommended number of threads per block is 256 according to the CUDA best practice guide
1225 ! see https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#thread-and-block-heuristics
1226 block_size = 256
1227
1228 ! make sure we do not use more threads per block than available for this kernel
1229 block_size = min(block_size, max_block_size)
1230#endif
1231
1232 end function accel_kernel_block_size
1233
1234 ! ----------------------------------------------------
1235
1237 subroutine accel_copy_buffer(dest, src, type, nval, offset_dest, offset_src, async)
1238 type(accel_mem_t), intent(inout) :: dest
1239 type(accel_mem_t), intent(in) :: src
1240 type(type_t), intent(in) :: type
1241 integer(int64), intent(in) :: nval
1242 integer(int64), optional, intent(in) :: offset_dest
1243 integer(int64), optional, intent(in) :: offset_src
1244 logical, optional, intent(in) :: async
1245
1246 integer(int64) :: type_size, offset_dest_, offset_src_
1247
1249 call profiling_in("ACCEL_COPY_BUFFER")
1250
1251 if (nval == 0) then
1252 call profiling_out("ACCEL_COPY_BUFFER")
1253 pop_sub(accel_copy_buffer)
1254 return
1255 end if
1256 assert(nval > 0)
1257
1258 type_size = types_get_size(type)
1259
1260 offset_dest_ = 0_int64
1261 if (present(offset_dest)) offset_dest_ = offset_dest*type_size
1262 offset_src_ = 0_int64
1263 if (present(offset_src)) offset_src_ = offset_src*type_size
1264
1265 assert(offset_dest_ + nval*type_size <= int(dest%size, int64)*types_get_size(dest%type))
1266 assert(offset_src_ + nval*type_size <= int(src%size, int64)*types_get_size(src%type))
1267
1268 call cuda_memcpy_dtod(dest%mem, src%mem, nval*type_size, offset_dest_, offset_src_)
1269
1270 if (.not. optional_default(async, .false.)) call accel_finish()
1271
1272 call profiling_out("ACCEL_COPY_BUFFER")
1273 pop_sub(accel_copy_buffer)
1274 end subroutine accel_copy_buffer
1275
1276 ! ----------------------------------------------------
1277
1278 subroutine accel_set_buffer_to(buffer, type, val, nval, offset, async)
1279 type(accel_mem_t), intent(inout) :: buffer
1280 type(type_t), intent(in) :: type
1281 integer(int8), intent(in) :: val
1282 integer(int64), intent(in) :: nval
1283 integer(int64), optional, intent(in) :: offset
1284 logical, optional, intent(in) :: async
1285
1286 integer(int64) :: nval_, offset_, type_size
1287
1288 push_sub(accel_set_buffer_to)
1290 if (nval == 0) then
1291 pop_sub(accel_set_buffer_to)
1292 return
1293 end if
1294 assert(nval > 0)
1295
1296 if (present(offset)) then
1297 assert(offset >= 0)
1298 if(offset > buffer%size) then
1299 pop_sub(accel_set_buffer_to)
1300 return
1301 end if
1302 end if
1303
1304 type_size = types_get_size(type)
1306 nval_ = nval*type_size
1307
1308 offset_ = 0_int64
1309 if (present(offset)) offset_ = offset*type_size
1310
1311 call cuda_mem_set_async(buffer%mem, val, nval_, offset_)
1312 if(.not. optional_default(async, .false.)) call accel_finish()
1313
1314 pop_sub(accel_set_buffer_to)
1315 end subroutine accel_set_buffer_to
1316
1317 ! ----------------------------------------------------
1318
1319 subroutine accel_set_buffer_to_zero_i8(buffer, type, nval, offset, async)
1320 type(accel_mem_t), intent(inout) :: buffer
1321 type(type_t), intent(in) :: type
1322 integer(int64), intent(in) :: nval
1323 integer(int64), optional, intent(in) :: offset
1324 logical, optional, intent(in) :: async
1327
1328 call accel_set_buffer_to(buffer, type, int(z'00', int8), nval, offset, async)
1329
1331 end subroutine accel_set_buffer_to_zero_i8
1332
1333 ! ----------------------------------------------------
1334
1335 subroutine accel_set_buffer_to_zero_i4(buffer, type, nval, offset, async)
1336 type(accel_mem_t), intent(inout) :: buffer
1337 type(type_t), intent(in) :: type
1338 integer(int32), intent(in) :: nval
1339 integer(int32), optional, intent(in) :: offset
1340 logical, optional, intent(in) :: async
1341
1343
1344 if (present(offset)) then
1345 call accel_set_buffer_to_zero_i8(buffer, type, int(nval, int64), int(offset, int64), async=async)
1346 else
1347 call accel_set_buffer_to_zero_i8(buffer, type, int(nval, int64), async=async)
1348 end if
1349
1351 end subroutine accel_set_buffer_to_zero_i4
1352
1353 ! ----------------------------------------------------
1354
1355 subroutine accel_check_bandwidth()
1356 integer :: itime
1357 integer, parameter :: times = 10
1358 integer :: size
1359 real(real64) :: time, stime
1360 real(real64) :: read_bw, write_bw
1361 type(accel_mem_t) :: buff
1362 real(real64), allocatable :: data(:)
1363
1364 call messages_new_line()
1365 call messages_write('Info: Benchmarking the bandwidth between main memory and device memory')
1366 call messages_new_line()
1367 call messages_info()
1368
1369 call messages_write(' Buffer size Read bw Write bw')
1370 call messages_new_line()
1371 call messages_write(' [MiB] [MiB/s] [MiB/s]')
1372 call messages_info()
1373
1374 size = 15000
1375 do
1376 safe_allocate(data(1:size))
1377 call accel_create_buffer(buff, accel_mem_read_write, type_float, size)
1378
1379 stime = loct_clock()
1380 do itime = 1, times
1381 call accel_write_buffer(buff, size, data)
1382 call accel_finish()
1383 end do
1384 time = (loct_clock() - stime)/real(times, real64)
1385
1386 write_bw = real(size, real64) *8.0_real64/time
1387
1388 stime = loct_clock()
1389 do itime = 1, times
1390 call accel_read_buffer(buff, size, data)
1391 end do
1392 call accel_finish()
1393
1394 time = (loct_clock() - stime)/real(times, real64)
1395 read_bw = real(size, real64) *8.0_real64/time
1396
1397 call messages_write(size*8.0_real64/1024.0_real64**2)
1398 call messages_write(write_bw/1024.0_real64**2, fmt = '(f10.1)')
1399 call messages_write(read_bw/1024.0_real64**2, fmt = '(f10.1)')
1400 call messages_info()
1401
1402 call accel_free_buffer(buff)
1403
1404 safe_deallocate_a(data)
1406 size = int(size*2.0)
1407
1408 if (size > 50000000) exit
1409 end do
1410 end subroutine accel_check_bandwidth
1411
1412 !------------------------------------------------------------
1413
1414 subroutine accel_kernel_global_init()
1415
1416 push_sub(accel_kernel_global_init)
1417
1418 nullify(head)
1419
1420 call cuda_program_map_init(accel%program_map)
1421
1422 call accel_kernel_list()
1423
1425 end subroutine accel_kernel_global_init
1426
1427 !------------------------------------------------------------
1428
1435 subroutine accel_kernel_list()
1436
1437 push_sub(accel_kernel_list)
1438
1439 call accel_program_add('axpy.cu', 'axpy<double>')
1440 call accel_program_add('axpy.cu', 'axpy<complex<double>>')
1441 call accel_program_add('axpy.cu', 'axpby<double>')
1442 call accel_program_add('axpy.cu', 'axpby<complex<double>>')
1443 call accel_program_add('axpy.cu', 'scal2v<double>')
1444 call accel_program_add('axpy.cu', 'scal2v<complex<double>, Conjugation::No>')
1445 call accel_program_add('axpy.cu', 'scal2v<complex<double>, Conjugation::Yes>')
1446 call accel_program_add('axpy.cu', 'axpy_vec<double>')
1447 call accel_program_add('axpy.cu', 'axpy_vec<complex<double>>')
1448 call accel_program_add('axpy.cu', 'scal_vec<double>')
1449 call accel_program_add('axpy.cu', 'scal_vec<complex<double>>')
1450 call accel_program_add('axpy.cu', 'xpay_vec<double>')
1451 call accel_program_add('axpy.cu', 'xpay_vec<complex<double>>')
1452 call accel_program_add('axpy.cu', &
1453 'batch_axpy_function<double, DimSpin::D1>')
1454 call accel_program_add('axpy.cu', &
1455 'batch_axpy_function<double, DimSpin::D2>')
1456 call accel_program_add('axpy.cu', &
1457 'batch_axpy_function<complex<double>, DimSpin::D1>')
1458 call accel_program_add('axpy.cu', &
1459 'batch_axpy_function<complex<double>, DimSpin::D2>')
1460 call accel_program_add('axpy.cu', &
1461 'batch_ax_function_py<double, DimSpin::D1>')
1462 call accel_program_add('axpy.cu', &
1463 'batch_ax_function_py<double, DimSpin::D2>')
1464 call accel_program_add('axpy.cu', &
1465 'batch_ax_function_py<complex<double>, DimSpin::D1>')
1466 call accel_program_add('axpy.cu', &
1467 'batch_ax_function_py<complex<double>, DimSpin::D2>')
1468
1469 call accel_program_add('batch_mul.cu', 'mul_batch<double>')
1470 call accel_program_add('batch_mul.cu', 'mul_mf<double, double>')
1471 call accel_program_add('batch_mul.cu', 'mul_batch<complex<double>, Conjugation::No>')
1472 call accel_program_add('batch_mul.cu', 'mul_batch<complex<double>, Conjugation::Yes>')
1473 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, double, Conjugation::No>')
1474 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, double, Conjugation::Yes>')
1475 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, complex<double>, Conjugation::No>')
1476 call accel_program_add('batch_mul.cu', 'mul_mf<complex<double>, complex<double>, Conjugation::Yes>')
1477
1478 call accel_program_add('boundaries.cu', 'boundaries_periodic<double>')
1479 call accel_program_add('boundaries.cu', 'boundaries_periodic_corr<double>')
1480 call accel_program_add('boundaries.cu', 'boundaries_periodic_recv<double>')
1481 call accel_program_add('boundaries.cu', 'boundaries_periodic_recv_corr<double>')
1482 call accel_program_add('boundaries.cu', 'boundaries_periodic_send<double>')
1483
1484 call accel_program_add('copy.cu', 'add_with_map<double>')
1485 call accel_program_add('copy.cu', 'copy<double>')
1486 call accel_program_add('copy.cu', 'copy_complex_to_real<double>')
1487 call accel_program_add('copy.cu', 'copy_real_to_complex<double>')
1488 call accel_program_add('copy.cu', 'copy_with_map<double>')
1489
1490 call accel_program_add('curl.cu', 'curl<double>')
1491 call accel_program_add('curl.cu', 'curl<complex<double>>')
1492
1493 call accel_program_add('density.cu', 'density<double, double>')
1494 call accel_program_add('density.cu', 'density<double, complex<double>>')
1495 call accel_program_add('density.cu', 'current_accumulate<double>')
1496 call accel_program_add('density.cu', 'density_spinors<double>')
1497
1498 call accel_program_add('dftu_projector.cu', 'dftu_pos_mat_elem<double>')
1499 call accel_program_add('dftu_projector.cu', 'dftu_pos_mat_elem_cmplx<double>')
1500 call accel_program_add('dftu_projector.cu', 'dftu_pos_mat_elem_cmplx_submesh<double>')
1501 call accel_program_add('dftu_projector.cu', 'dftu_pos_mat_elem_phase<double>')
1502 call accel_program_add('dftu_projector.cu', 'dftu_pos_mat_elem_submesh<double>')
1503 call accel_program_add('dftu_projector.cu', 'dftu_projector_bra<double>')
1504 call accel_program_add('dftu_projector.cu', 'dftu_projector_bra_cmplx<double>')
1505 call accel_program_add('dftu_projector.cu', 'dftu_projector_bra_cmplx_submesh<double>')
1506 call accel_program_add('dftu_projector.cu', 'dftu_projector_bra_submesh<double>')
1507 call accel_program_add('dftu_projector.cu', 'dftu_projector_ket<double>')
1508 call accel_program_add('dftu_projector.cu', 'dftu_projector_ket_cmplx<double>')
1509 call accel_program_add('dftu_projector.cu', 'dftu_projector_ket_cmplx_submesh<double>')
1510 call accel_program_add('dftu_projector.cu', 'dftu_projector_ket_submesh<double>')
1511
1512 call accel_program_add('exchange_local.cu', &
1513 'exchange_accumulate_batch<double, double, DimSpin::D1>')
1514 call accel_program_add('exchange_local.cu', &
1515 'exchange_accumulate_return_batch<double, double, DimSpin::D1>')
1516 call accel_program_add('exchange_local.cu', &
1517 'exchange_codensity_batch<double, DimSpin::D1>')
1518 call accel_program_add('exchange_local.cu', &
1519 'exchange_accumulate_batch<double, double, DimSpin::D2>')
1520 call accel_program_add('exchange_local.cu', &
1521 'exchange_accumulate_return_batch<double, double, DimSpin::D2>')
1522 call accel_program_add('exchange_local.cu', &
1523 'exchange_codensity_batch<double, DimSpin::D2>')
1524 call accel_program_add('exchange_local.cu', &
1525 'exchange_accumulate_batch<double, complex<double>, DimSpin::D1>')
1526 call accel_program_add('exchange_local.cu', &
1527 'exchange_accumulate_return_batch<double, complex<double>, DimSpin::D1>')
1528 call accel_program_add('exchange_local.cu', &
1529 'exchange_codensity_batch<complex<double>, DimSpin::D1>')
1530 call accel_program_add('exchange_local.cu', &
1531 'exchange_accumulate_batch<double, complex<double>, DimSpin::D2>')
1532 call accel_program_add('exchange_local.cu', &
1533 'exchange_accumulate_return_batch<double, complex<double>, DimSpin::D2>')
1534 call accel_program_add('exchange_local.cu', &
1535 'exchange_codensity_batch<complex<double>, DimSpin::D2>')
1536
1537 call accel_program_add('forces.cu', '(density_gradient<double, double>)')
1538 call accel_program_add('forces.cu', '(density_gradient<double, complex<double>>)')
1539
1540 call accel_program_add('get_points.cu', 'get_selected_points<double>')
1541
1542 call accel_program_add('ghost.cu', 'ghost_reorder<double>')
1543
1544 call accel_program_add('mesh_batch.cu', 'zdot_matrix_spinors<double>')
1545
1546 call accel_program_add('mesh_batch_single.cu', 'dbatch_dotpv_partial<double>')
1547 call accel_program_add('mesh_batch_single.cu', &
1548 'dbatch_dotpv_reduce<double, DimSpin::D1>')
1549 call accel_program_add('mesh_batch_single.cu', &
1550 'dbatch_dotpv_reduce<double, DimSpin::D2>')
1551 call accel_program_add('mesh_batch_single.cu', &
1552 'batch_mf_dotp<double, DimSpin::D1>')
1553 call accel_program_add('mesh_batch_single.cu', &
1554 'batch_mf_dotp<double, DimSpin::D2>')
1555 call accel_program_add('mesh_batch_single.cu', 'zbatch_dotpv_partial<double>')
1556 call accel_program_add('mesh_batch_single.cu', &
1557 'zbatch_dotpv_reduce<double, DimSpin::D1>')
1558 call accel_program_add('mesh_batch_single.cu', &
1559 'zbatch_dotpv_reduce<double, DimSpin::D2>')
1560 call accel_program_add('mesh_batch_single.cu', &
1561 'batch_mf_dotp<complex<double>, DimSpin::D1>')
1562 call accel_program_add('mesh_batch_single.cu', &
1563 'batch_mf_dotp<complex<double>, DimSpin::D2>')
1564
1565 call accel_program_add('mesh_interpolate.cu', &
1566 'mesh_interpolate<double, double, Dim::D1>')
1567 call accel_program_add('mesh_interpolate.cu', &
1568 'mesh_interpolate<double, double, Dim::D2>')
1569 call accel_program_add('mesh_interpolate.cu', &
1570 'mesh_interpolate<double, double, Dim::D3>')
1571 call accel_program_add('mesh_interpolate.cu', &
1572 'mesh_interpolate<double, complex<double>, Dim::D1>')
1573 call accel_program_add('mesh_interpolate.cu', &
1574 'mesh_interpolate<double, complex<double>, Dim::D2>')
1575 call accel_program_add('mesh_interpolate.cu', &
1576 'mesh_interpolate<double, complex<double>, Dim::D3>')
1577
1578 call accel_program_add('mesh_to_cube.cu', 'cube_to_mesh_batch<double>')
1579 call accel_program_add('mesh_to_cube.cu', 'mesh_to_cube_batch<double>')
1580 call accel_program_add('mesh_to_cube.cu', 'cube_to_mesh_batch<complex<double>>')
1581 call accel_program_add('mesh_to_cube.cu', 'mesh_to_cube_batch<complex<double>>')
1582
1583 call accel_program_add('mul.cu', 'zmul_batch<double, double>')
1584 call accel_program_add('mul.cu', 'zmul_batch<double, complex<double>>')
1585
1586 call accel_program_add('operate.cu', 'operate<double>')
1587 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Direct>')
1588 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Indirect>')
1589 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Direct, Symmetry::Antisymmetric>')
1590 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Direct, Symmetry::Symmetric>')
1591 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Indirect, Symmetry::Antisymmetric>')
1592 call accel_program_add('operate.cu', 'operate_map<double, Indexing::Indirect, Symmetry::Symmetric>')
1593
1594 call accel_program_add('pack.cu', 'pack<double>')
1595 call accel_program_add('pack.cu', 'unpack<double>')
1596 call accel_program_add('pack.cu', 'pack<complex<double>>')
1597 call accel_program_add('pack.cu', 'unpack<complex<double>>')
1598
1599 call accel_program_add('pes.cu', 'zpes_flux_sph_integrate<double>')
1600 call accel_program_add('pes.cu', 'zpes_flux_sph_integxx<double>')
1601 call accel_program_add('pes.cu', 'zpes_flux_sph_integxx_2<double>')
1602
1603 call accel_program_add('phase.cu', 'phase<double>')
1604 call accel_program_add('phase.cu', 'phase_hamiltonian<double>')
1605 call accel_program_add('phase.cu', 'update_phases<double, Dim::D1>')
1606 call accel_program_add('phase.cu', 'update_phases<double, Dim::D2>')
1607 call accel_program_add('phase.cu', 'update_phases<double, Dim::D3>')
1608
1609 call accel_program_add('phase_spiral.cu', 'phase_spiral_apply<double>')
1610
1611 call accel_program_add('pml.cu', 'pml_apply<double>')
1612 call accel_program_add('pml.cu', 'pml_apply_new<double>')
1613 call accel_program_add('pml.cu', 'pml_copy<double>')
1614 call accel_program_add('pml.cu', 'pml_update_conv<double>')
1615 call accel_program_add('pml.cu', 'pml_update_new<double>')
1616
1617 call accel_program_add('points.cu', 'get_points<double>')
1618 call accel_program_add('points.cu', 'set_points<double>')
1619
1620 call accel_program_add('projector.cu', 'projector_bra_force<double, double>')
1621 call accel_program_add('projector.cu', 'projector_bra_force_phase<double, double>')
1622 call accel_program_add('projector.cu', 'projector_bra_gather<double>')
1623 call accel_program_add('projector.cu', 'projector_bra_scatter_real<double, double>')
1624 call accel_program_add('projector.cu', 'projector_ket<double>')
1625 call accel_program_add('projector.cu', 'projector_ket_phase<double, double>')
1626 call accel_program_add('projector.cu', 'projector_ket_phase_spiral<double, double>')
1627 call accel_program_add('projector.cu', 'dprojector_mix<double>')
1628 call accel_program_add('projector.cu', 'projector_r_vnl_bra<double, double>')
1629 call accel_program_add('projector.cu', 'projector_r_vnl_bra_phase<double, double>')
1630 call accel_program_add('projector.cu', 'projector_r_vnl_ket<double, double>')
1631 call accel_program_add('projector.cu', 'projector_r_vnl_ket_phase<double, double>')
1632 call accel_program_add('projector.cu', 'projector_bra_phase_gather<double>')
1633 call accel_program_add('projector.cu', 'projector_bra_phase_spiral_gather<double>')
1634 call accel_program_add('projector.cu', 'projector_bra_force<double, complex<double>>')
1635 call accel_program_add('projector.cu', 'projector_bra_force_phase<double, complex<double>>')
1636 call accel_program_add('projector.cu', 'projector_bra_gather<complex<double>>')
1637 call accel_program_add('projector.cu', 'projector_bra_scatter_complex<double, complex<double>>')
1638 call accel_program_add('projector.cu', 'projector_bra_scatter_real<double, complex<double>>')
1639 call accel_program_add('projector.cu', 'projector_ket<complex<double>>')
1640 call accel_program_add('projector.cu', 'projector_ket_phase<double, complex<double>>')
1641 call accel_program_add('projector.cu', 'projector_ket_phase_spiral<double, complex<double>>')
1642 call accel_program_add('projector.cu', 'zprojector_mix<double>')
1643 call accel_program_add('projector.cu', 'projector_r_vnl_bra<double, complex<double>>')
1644 call accel_program_add('projector.cu', 'projector_r_vnl_bra_phase<double, complex<double>>')
1645 call accel_program_add('projector.cu', 'projector_r_vnl_ket<double, complex<double>>')
1646 call accel_program_add('projector.cu', 'projector_r_vnl_ket_phase<double, complex<double>>')
1647
1648 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra<double, double>')
1649 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra_phase<double, double>')
1650 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket<double, double>')
1651 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket_phase<double, double>')
1652 call accel_program_add('projector_commutator.cu', 'dprojector_mix_commutator<double>')
1653 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra<double, complex<double>>')
1654 call accel_program_add('projector_commutator.cu', 'projector_commutator_bra_phase<double, complex<double>>')
1655 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket<double, complex<double>>')
1656 call accel_program_add('projector_commutator.cu', 'projector_commutator_ket_phase<double, complex<double>>')
1657 call accel_program_add('projector_commutator.cu', 'zprojector_mix_commutator<double>')
1658
1659 call accel_program_add('split.cu', 'merge_complex<double>')
1660 call accel_program_add('split.cu', 'split_complex<double>')
1661
1662 call accel_program_add('symmetrize_batch.cu', &
1663 '(symmetrizer_apply_single_batch<double, Conjugation::No>)')
1664 call accel_program_add('symmetrize_batch.cu', &
1665 '(symmetrizer_apply_single_batch<double, Conjugation::Yes>)')
1666 call accel_program_add('symmetrize_batch.cu', &
1667 '(symmetrizer_apply_single_batch<complex<double>, Conjugation::No>)')
1668 call accel_program_add('symmetrize_batch.cu', &
1669 '(symmetrizer_apply_single_batch<complex<double>, Conjugation::Yes>)')
1670
1671 call accel_program_add('uvw_to_xyz.cu', &
1672 'uvw_to_xyz<double, Dim::D1, double*, int, double*, int>')
1673 call accel_program_add('uvw_to_xyz.cu', &
1674 'uvw_to_xyz<double, Dim::D2, double*, int, double*, int, double*, int, double*, int>')
1675 call accel_program_add('uvw_to_xyz.cu', &
1676 'uvw_to_xyz<double, Dim::D3, double*, int, double*, int, double*, int, double*, int, double*, int, double*, int>')
1677
1678 call accel_program_add('vpsi.cu', 'vpsi<double>')
1679 call accel_program_add('vpsi.cu', 'vpsi_complex<double>')
1680 call accel_program_add('vpsi.cu', 'vpsi_spinors<double>')
1681 call accel_program_add('vpsi.cu', 'vpsi_spinors_complex<double>')
1682
1683 call accel_program_add('xc_dens_block.cu', 'xc_dens_apply_corrections<double>')
1684 call accel_program_add('xc_dens_block.cu', 'xc_dens_extract_block<double>')
1685
1686 pop_sub(accel_kernel_list)
1687 end subroutine accel_kernel_list
1688
1689 !------------------------------------------------------------
1690
1696 subroutine accel_program_add(file_name, name)
1697 character(len=*), intent(in) :: file_name
1698 character(len=*), intent(in) :: name
1699
1700 push_sub(accel_program_add)
1701
1702 call cuda_program_register(accel%program_map, string_f_to_c(trim(file_name)), &
1703 string_f_to_c(trim(name)))
1704
1705 pop_sub(accel_program_add)
1706 end subroutine accel_program_add
1707
1708 !------------------------------------------------------------
1709
1710 subroutine accel_kernel_global_end()
1711 type(accel_kernel_t), pointer :: next_head
1712
1713 push_sub(accel_kernel_global_end)
1714
1715 do
1716 if (.not. associated(head)) exit
1717 next_head => head%next
1719 head => next_head
1720 end do
1721
1722 if (accel_is_enabled()) then
1723 call cuda_program_map_end(accel%program_map)
1724 end if
1725
1727 end subroutine accel_kernel_global_end
1728
1729 !------------------------------------------------------------
1736 subroutine accel_kernel_build(this, file_name, kernel_name, flags)
1737 type(accel_kernel_t), intent(inout) :: this
1738 character(len=*), intent(in) :: file_name
1739 character(len=*), intent(in) :: kernel_name
1740 character(len=*), optional, intent(in) :: flags
1741
1742#ifdef HAVE_CUDA
1743 character(len=1000) :: all_flags
1744#endif
1745
1746 push_sub(accel_kernel_build)
1747
1748 call profiling_in("ACCEL_COMPILE", exclude = .true.)
1749
1750#ifdef HAVE_CUDA
1751 all_flags = '-I'//trim(conf%share)//'/kernels/'//" "//trim(accel%debug_flag)
1752
1753 if (present(flags)) then
1754 all_flags = trim(all_flags)//' '//trim(flags)
1755 end if
1756
1757 call cuda_program_build(accel%program_map, accel%device%cuda_device, &
1758 string_f_to_c(trim(file_name)), string_f_to_c(trim(all_flags)))
1759
1760 call cuda_program_get_kernel(this%cuda_kernel, accel%program_map, &
1761 string_f_to_c(trim(file_name)), string_f_to_c(trim(all_flags)), &
1762 string_f_to_c(trim(kernel_name)))
1763 call cuda_alloc_arg_array(this%arguments)
1764#endif
1765
1766 this%initialized = .true.
1767 this%kernel_name = trim(kernel_name)
1768
1769 call profiling_out("ACCEL_COMPILE")
1770
1771 pop_sub(accel_kernel_build)
1772 end subroutine accel_kernel_build
1773
1774 !------------------------------------------------------------
1776 subroutine accel_kernel_end(this)
1777 type(accel_kernel_t), intent(inout) :: this
1778
1779 push_sub(accel_kernel_end)
1780
1781#ifdef HAVE_CUDA
1782 call cuda_free_arg_array(this%arguments)
1783 call cuda_release_kernel(this%cuda_kernel)
1784 ! modules are not released here, since they are not associated to a kernel
1785#endif
1786
1787 this%initialized = .false.
1788
1789 pop_sub(accel_kernel_end)
1790 end subroutine accel_kernel_end
1791
1792 !------------------------------------------------------------
1793
1794 subroutine accel_kernel_start_call(this, file_name, kernel_name, flags)
1795 type(accel_kernel_t), target, intent(inout) :: this
1796 character(len=*), intent(in) :: file_name
1797 character(len=*), intent(in) :: kernel_name
1798 character(len=*), optional, intent(in) :: flags
1799
1800 push_sub(accel_kernel_start_call)
1801
1802 if (.not. this%initialized) then
1803 call accel_kernel_build(this, file_name, kernel_name, flags)
1804 this%next => head
1805 head => this
1806 end if
1807
1809 end subroutine accel_kernel_start_call
1810
1811 !--------------------------------------------------------------
1812
1813 integer(int64) pure function accel_global_memory_size() result(size)
1814
1815 size = accel%global_memory_size
1816
1817 end function accel_global_memory_size
1818
1819 !--------------------------------------------------------------
1820
1821 integer(int64) pure function accel_shared_memory_size() result(size)
1822
1823 size = accel%shared_memory_size
1824
1825 end function accel_shared_memory_size
1826 !--------------------------------------------------------------
1828 integer pure function accel_max_size_per_dim(dim) result(size)
1829 integer, intent(in) :: dim
1830
1831 size = 0
1832#ifdef HAVE_CUDA
1833 size = 32768
1834 if (dim == 1) size = 2**30
1835#endif
1836 end function accel_max_size_per_dim
1837
1838 ! ------------------------------------------------------
1840 subroutine accel_set_stream(stream_number)
1841 integer, intent(in) :: stream_number
1842
1843 push_sub(accel_set_stream)
1844
1845 if (accel_is_enabled()) then
1846#ifdef HAVE_CUDA
1847 call cuda_set_stream(accel%cuda_stream, stream_number)
1848 call cublas_set_stream(accel%cublas_handle, accel%cuda_stream)
1849#endif
1850 end if
1851
1852 pop_sub(accel_set_stream)
1853 end subroutine accel_set_stream
1855 ! ------------------------------------------------------
1856
1857 subroutine accel_get_stream(stream_number)
1858 integer, intent(inout) :: stream_number
1859
1860 push_sub(accel_get_stream)
1861
1862 if (accel_is_enabled()) then
1863#ifdef HAVE_CUDA
1864 call cuda_get_stream(stream_number)
1865#endif
1866 end if
1867
1868 pop_sub(accel_get_stream)
1869 end subroutine accel_get_stream
1870
1871 ! ------------------------------------------------------
1872
1875
1876 if (accel_is_enabled()) then
1877#ifdef HAVE_CUDA
1878 call cuda_synchronize_all_streams()
1879#endif
1880 end if
1881
1883 end subroutine accel_synchronize_all_streams
1884
1885 function daccel_get_pointer_with_offset(buffer, offset) result(buffer_offset)
1886 type(c_ptr), intent(in) :: buffer
1887 integer(int64), intent(in) :: offset
1888 type(c_ptr) :: buffer_offset
1889
1891#ifdef HAVE_CUDA
1892 call cuda_get_pointer_with_offset(buffer, offset, buffer_offset)
1893#else
1894 ! this is needed to make the compiler happy for non-GPU compilations
1895 buffer_offset = buffer
1896#endif
1899
1900 function zaccel_get_pointer_with_offset(buffer, offset) result(buffer_offset)
1901 type(c_ptr), intent(in) :: buffer
1902 integer(int64), intent(in) :: offset
1903 type(c_ptr) :: buffer_offset
1904
1906#ifdef HAVE_CUDA
1907 call cuda_get_pointer_with_offset(buffer, 2_int64*offset, buffer_offset)
1908#else
1909 ! this is needed to make the compiler happy for non-GPU compilations
1910 buffer_offset = buffer
1911#endif
1914
1915 subroutine accel_clean_pointer(buffer)
1916 type(c_ptr), intent(in) :: buffer
1917
1918 push_sub(accel_clean_pointer)
1919#ifdef HAVE_CUDA
1920 call cuda_clean_pointer(buffer)
1921#endif
1922 pop_sub(accel_clean_pointer)
1923 end subroutine accel_clean_pointer
1924
1928 subroutine accel_get_unfolded_size(size, grid_size, thread_block_size)
1929 integer(int64), intent(in) :: size
1930 integer(int64), intent(out) :: grid_size
1931 integer(int64), intent(out) :: thread_block_size
1932
1933 push_sub(accel_get_unfolded_size)
1934#ifdef __HIP_PLATFORM_AMD__
1935 ! not benefitial for AMD chips
1936 grid_size = 1_int64
1937 thread_block_size = size
1938#else
1939 grid_size = size
1940 thread_block_size = accel%warp_size
1941#endif
1943 end subroutine accel_get_unfolded_size
1944
1945#include "undef.F90"
1946#include "real.F90"
1947#include "accel_inc.F90"
1948
1949#include "undef.F90"
1950#include "complex.F90"
1951#include "accel_inc.F90"
1952
1953#include "undef.F90"
1954#include "integer.F90"
1955#include "accel_inc.F90"
1956
1957#include "undef.F90"
1958#include "integer8.F90"
1959#include "accel_inc.F90"
1960
1961end module accel_oct_m
1962
1963!! Local Variables:
1964!! mode: f90
1965!! coding: utf-8
1966!! End:
subroutine device_info()
Definition: accel.F90:631
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:822
subroutine laccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6197
subroutine zaccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3986
subroutine, public accel_clean_pointer(buffer)
Definition: accel.F90:1870
subroutine accel_kernel_global_end()
Definition: accel.F90:1681
subroutine zaccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3164
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:1883
subroutine laccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5993
subroutine laccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5752
subroutine iaccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:4226
pure logical function, public accel_allow_cpu_only()
Definition: accel.F90:405
subroutine daccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2800
subroutine zaccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3806
subroutine daccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2522
subroutine zaccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3893
subroutine laccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5776
subroutine zaccel_create_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:4035
subroutine daccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2280
subroutine laccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5351
subroutine daccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2252
subroutine laccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6080
subroutine zaccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3643
subroutine zaccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:3475
integer function, public accel_kernel_block_size(kernel)
Definition: accel.F90:1194
subroutine zaccel_write_buffer_single(this, data, async)
Definition: accel.F90:3061
subroutine daccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:2441
subroutine iaccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5103
subroutine zaccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:3534
subroutine laccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6104
subroutine iaccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4438
subroutine zaccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3439
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:772
subroutine laccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5592
subroutine zaccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3565
subroutine iaccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:4207
subroutine zaccel_release_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:4062
subroutine laccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:5429
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:986
subroutine daccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2095
subroutine iaccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:4365
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
Definition: accel.F90:1749
subroutine iaccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4257
subroutine zaccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3214
subroutine iaccel_release_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:5155
subroutine iaccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4839
subroutine zaccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:3310
subroutine, public accel_get_stream(stream_number)
Definition: accel.F90:1812
subroutine accel_create_buffer_4(this, flags, type, size, set_zero, async)
Definition: accel.F90:917
subroutine zaccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:3692
subroutine iaccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4335
integer(int64) pure function, public accel_global_memory_size()
Definition: accel.F90:1768
subroutine daccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2496
subroutine laccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:5301
subroutine daccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:2422
subroutine daccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:2040
subroutine zaccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:3877
subroutine daccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2917
subroutine iaccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:4658
subroutine daccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2893
integer(int64) function accel_padded_size_i8(nn)
Definition: accel.F90:887
subroutine accel_check_bandwidth()
Definition: accel.F90:1326
subroutine iaccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4466
subroutine daccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2747
subroutine laccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:5662
subroutine daccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:1981
subroutine iaccel_create_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:5128
subroutine zaccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:3673
subroutine iaccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5054
subroutine, public accel_finish()
Definition: accel.F90:1104
subroutine laccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5560
subroutine accel_kernel_global_init()
Definition: accel.F90:1385
subroutine zaccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3746
subroutine daccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2550
subroutine accel_kernel_run_4(kernel, gridsizes, blocksizes, shared_memory_size)
Run a kernel with 4-byte integer sizes.
Definition: accel.F90:1176
subroutine zaccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:3114
subroutine iaccel_get_device_pointer_1(host_pointer, device_pointer, dimensions)
Definition: accel.F90:4986
subroutine laccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:6027
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:1208
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:869
subroutine laccel_create_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:6222
subroutine, public accel_ensure_buffer_size(buffer, flags, type, required_size, set_zero, async)
Definition: accel.F90:1072
subroutine accel_set_buffer_to(buffer, type, val, nval, offset, async)
Definition: accel.F90:1249
subroutine, public accel_move_buffer(buffer_from, buffer_to)
Move the buffer memory from the first buffer to the second.
Definition: accel.F90:1029
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
Definition: accel.F90:1055
subroutine laccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:6064
subroutine iaccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4307
subroutine daccel_write_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:2021
subroutine daccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:2580
subroutine zaccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:3515
subroutine iaccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4498
subroutine daccel_read_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2472
subroutine laccel_write_buffer_single(this, data, async)
Definition: accel.F90:5248
subroutine laccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:5830
subroutine daccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2824
subroutine accel_kernel_run_8(kernel, gridsizes, blocksizes, shared_memory_size)
Run a kernel with 8-byte integer sizes.
Definition: accel.F90:1138
subroutine iaccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:4804
subroutine zaccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:3272
subroutine zaccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:3291
subroutine accel_set_buffer_to_zero_i8(buffer, type, nval, offset, async)
Definition: accel.F90:1290
subroutine zaccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3961
logical pure function, public accel_buffer_is_allocated(this)
Definition: accel.F90:1096
integer, parameter, public accel_mem_read_write
Definition: accel.F90:187
subroutine daccel_create_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:2942
subroutine accel_kernel_end(this)
Definition: accel.F90:1731
subroutine laccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5532
subroutine zaccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3405
subroutine zaccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3917
subroutine daccel_write_buffer_3(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2071
subroutine laccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:5898
type(c_ptr) function, public daccel_get_pointer_with_offset(buffer, offset)
Definition: accel.F90:1840
subroutine iaccel_write_buffer_single(this, data, async)
Definition: accel.F90:4154
subroutine iaccel_get_device_pointer_2(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5010
integer pure function, public accel_max_size_per_dim(dim)
Definition: accel.F90:1783
subroutine zaccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3589
subroutine iaccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:4568
subroutine daccel_read_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:2382
subroutine iaccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:4785
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:792
subroutine iaccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4899
subroutine laccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5375
subroutine laccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:5459
subroutine zaccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:3133
subroutine laccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:5860
subroutine laccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6173
subroutine iaccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5032
subroutine zaccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3188
subroutine zaccel_write_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:3345
subroutine daccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:2784
subroutine iaccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:4608
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:839
subroutine, public accel_kernel_build(this, file_name, kernel_name, flags)
Compile the program that contains a given kernel.
Definition: accel.F90:1707
subroutine, public accel_init(base_grp, namespace)
Definition: accel.F90:415
subroutine, public accel_end(namespace)
Definition: accel.F90:688
subroutine laccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:5261
subroutine daccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2149
subroutine zaccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:3615
subroutine, public accel_synchronize_all_streams()
Definition: accel.F90:1828
subroutine, public accel_set_stream(stream_number)
Definition: accel.F90:1795
subroutine laccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:5721
subroutine daccel_release_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:2969
subroutine iaccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4867
subroutine iaccel_read_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4682
subroutine laccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6148
subroutine iaccel_read_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:4766
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:807
subroutine iaccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4532
integer(int32) function accel_padded_size_i4(nn)
Definition: accel.F90:908
subroutine accel_set_buffer_to_zero_i4(buffer, type, nval, offset, async)
Definition: accel.F90:1306
subroutine daccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:2346
subroutine laccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:5478
subroutine iaccel_get_device_pointer_2l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:5079
subroutine iaccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:4403
pure logical function, public accel_is_enabled()
Definition: accel.F90:395
subroutine zaccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3840
subroutine daccel_write_buffer_0_int32(this, n1, data, offset, async)
Definition: accel.F90:2179
subroutine iaccel_write_buffer_4(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:4281
subroutine daccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:2217
subroutine iaccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:4384
integer, parameter, public accel_mem_write_only
Definition: accel.F90:187
subroutine zaccel_write_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3373
subroutine daccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:2653
subroutine laccel_write_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:5626
subroutine laccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:5879
subroutine daccel_read_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:2599
subroutine laccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:5961
subroutine daccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2121
subroutine daccel_get_device_pointer_1l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2868
subroutine laccel_release_blas_alpha_beta_buffer(this, data, async)
Definition: accel.F90:6249
subroutine iaccel_read_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:4627
subroutine laccel_write_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5401
subroutine laccel_write_buffer_2(this, n1, n2, data, offset, async)
Definition: accel.F90:5320
subroutine daccel_write_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2312
subroutine laccel_write_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:5497
subroutine zaccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:3939
type(c_ptr) function, public zaccel_get_pointer_with_offset(buffer, offset)
Definition: accel.F90:1855
subroutine iaccel_read_buffer_6_int32(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4933
subroutine laccel_read_buffer_3_int32(this, n1, n2, n3, data, offset, async)
Definition: accel.F90:5933
subroutine daccel_write_buffer_single(this, data, async)
Definition: accel.F90:1968
subroutine daccel_write_buffer_1_int32(this, n1, data, offset, async)
Definition: accel.F90:2198
subroutine zaccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:3074
type(accel_t), public accel
Definition: accel.F90:251
subroutine laccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:6126
subroutine iaccel_read_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:4736
integer(int64) pure function, public accel_shared_memory_size()
Definition: accel.F90:1776
integer pure function, public accel_max_block_size()
Definition: accel.F90:1188
subroutine iaccel_set_kernel_arg_data(kernel, narg, data)
Definition: accel.F90:4970
subroutine daccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:2618
subroutine iaccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:4708
subroutine iaccel_write_buffer_0(this, n1, data, offset, async)
Definition: accel.F90:4167
subroutine zaccel_get_device_pointer_3l(host_pointer, device_pointer, dimensions)
Definition: accel.F90:4010
subroutine accel_create_buffer_8(this, flags, type, size, set_zero, async)
Definition: accel.F90:930
subroutine laccel_read_buffer_1(this, n1, data, offset, async)
Definition: accel.F90:5702
subroutine daccel_read_buffer_5_int32(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:2713
subroutine daccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:2681
subroutine accel_program_add(file_name, name)
Register a kernel for later retrieval.
Definition: accel.F90:1667
subroutine accel_set_kernel_arg_buffer(kernel, narg, buffer)
Definition: accel.F90:1116
subroutine accel_kernel_list()
The kernels each source provides.
Definition: accel.F90:1406
subroutine laccel_read_buffer_5(this, n1, n2, n3, n4, n5, data, offset, async)
Definition: accel.F90:5802
subroutine zaccel_read_buffer_2_int32(this, n1, n2, data, offset, async)
Definition: accel.F90:3711
subroutine zaccel_write_buffer_6(this, n1, n2, n3, n4, n5, n6, data, offset, async)
Definition: accel.F90:3242
subroutine daccel_get_device_pointer_3(host_pointer, device_pointer, dimensions)
Definition: accel.F90:2846
type(accel_kernel_t), pointer head
Definition: accel.F90:389
subroutine zaccel_read_buffer_4_int32(this, n1, n2, n3, n4, data, offset, async)
Definition: accel.F90:3774
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
complex(real64), parameter, public m_z0
Definition: global.F90:210
complex(real64), parameter, public m_z1
Definition: global.F90:211
real(real64), parameter, public m_one
Definition: global.F90:201
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
type(type_t), parameter, public type_cmplx
Definition: types.F90:136
integer pure function, public types_get_size(this)
Definition: types.F90:154
type(type_t), parameter, public type_float
Definition: types.F90:135
type(type_t), parameter, public type_none
Definition: types.F90:134
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)