71 integer,
public :: nst
72 integer,
public :: dim
75 integer,
allocatable :: ist_idim_index(:, :)
80 integer,
allocatable,
public :: ist(:)
87 logical :: is_allocated
90 integer,
public :: nst_linear
96 integer :: status_host
105 type(type_t) :: type_of
106 integer :: device_buffer_count
107 integer :: host_buffer_count
108 logical :: special_memory
109 logical :: needs_finish_unpack
113 real(real64),
pointer,
contiguous,
public :: dff(:, :, :)
115 complex(real64),
pointer,
contiguous,
public :: zff(:, :, :)
117 real(real64),
pointer,
contiguous,
public :: dff_linear(:, :)
119 complex(real64),
pointer,
contiguous,
public :: zff_linear(:, :)
123 real(real64),
pointer,
contiguous,
public :: dff_pack(:, :)
125 complex(real64),
pointer,
contiguous,
public :: zff_pack(:, :)
129 real(real32),
pointer,
contiguous,
public :: sff(:, :, :)
130 complex(real32),
pointer,
contiguous,
public :: cff(:, :, :)
131 real(real32),
pointer,
contiguous,
public :: sff_linear(:, :)
132 complex(real32),
pointer,
contiguous,
public :: cff_linear(:, :)
133 real(real32),
pointer,
contiguous,
public :: sff_pack(:, :)
134 complex(real32),
pointer,
contiguous,
public :: cff_pack(:, :)
136 integer(int64),
public :: pack_size(1:2)
138 integer(int64),
public :: pack_size_real(1:2)
142 type(accel_mem_t),
public :: ff_device
152 generic :: do_pack => do_pack_generic, do_pack_target
216 integer,
public,
parameter :: &
217 batch_not_packed = 0, & !< functions are stored in CPU memory, unpacked order
235 class(
batch_t),
intent(inout) :: this
236 logical,
optional,
intent(in) :: copy
241 if (this%own_memory .and. this%is_packed())
then
244 call this%deallocate_packed_device()
247 call this%deallocate_packed_host()
251 this%host_buffer_count = 0
252 this%device_buffer_count = 0
257 if (this%is_allocated)
then
258 call this%deallocate_unpacked_host()
261 safe_deallocate_a(this%ist_idim_index)
262 safe_deallocate_a(this%ist)
273 class(
batch_t),
intent(inout) :: this
277 this%is_allocated = .false.
279 if (this%special_memory)
then
280 if (
associated(this%dff))
then
283 if (
associated(this%zff))
then
286 if (
associated(this%sff))
then
289 if (
associated(this%cff))
then
293 safe_deallocate_p(this%dff)
294 safe_deallocate_p(this%zff)
295 safe_deallocate_p(this%sff)
296 safe_deallocate_p(this%cff)
299 nullify(this%dff_linear)
301 nullify(this%zff_linear)
303 nullify(this%sff_linear)
305 nullify(this%cff_linear)
320 if (this%special_memory)
then
321 if (
associated(this%dff_pack))
then
324 if (
associated(this%zff_pack))
then
327 if (
associated(this%sff_pack))
then
330 if (
associated(this%cff_pack))
then
334 safe_deallocate_p(this%dff_pack)
335 safe_deallocate_p(this%zff_pack)
336 safe_deallocate_p(this%sff_pack)
337 safe_deallocate_p(this%cff_pack)
339 nullify(this%dff_pack)
340 nullify(this%zff_pack)
341 nullify(this%sff_pack)
342 nullify(this%cff_pack)
351 class(
batch_t),
intent(inout) :: this
366 class(
batch_t),
intent(inout) :: this
371 call this%dallocate_unpacked_host()
373 call this%zallocate_unpacked_host()
375 call this%sallocate_unpacked_host()
377 call this%callocate_unpacked_host()
389 class(
batch_t),
intent(inout) :: this
394 call this%dallocate_packed_host()
396 call this%zallocate_packed_host()
398 call this%sallocate_packed_host()
400 call this%callocate_packed_host()
412 class(
batch_t),
intent(inout) :: this
417 product(this%pack_size))
430 type(
batch_t),
intent(out) :: this
431 integer,
intent(in) :: dim
432 integer,
intent(in) :: nst
433 integer,
intent(in) :: np
437 this%is_allocated = .false.
438 this%own_memory = .false.
439 this%special_memory = .false.
440 this%needs_finish_unpack = .false.
445 this%nst_linear = nst*dim
448 this%device_buffer_count = 0
449 this%host_buffer_count = 0
454 safe_allocate(this%ist_idim_index(1:this%nst_linear, 1:this%ndims))
455 safe_allocate(this%ist(1:this%nst))
457 nullify(this%dff, this%zff, this%dff_linear, this%zff_linear)
458 nullify(this%dff_pack, this%zff_pack)
459 nullify(this%sff, this%cff, this%sff_linear, this%cff_linear)
460 nullify(this%sff_pack, this%cff_pack)
471 subroutine batch_clone_to(this, dest, pack, copy_data, new_np, special, dest_type)
472 class(
batch_t),
intent(in) :: this
473 class(
batch_t),
allocatable,
intent(out) :: dest
474 logical,
optional,
intent(in) :: pack
476 logical,
optional,
intent(in) :: copy_data
478 integer,
optional,
intent(in) :: new_np
479 logical,
optional,
intent(in) :: special
481 type(
type_t),
optional,
intent(in) :: dest_type
485 if (.not.
allocated(dest))
then
486 safe_allocate_type(
batch_t, dest)
488 message(1) =
"Internal error: destination batch in batch_clone_to has been previously allocated."
492 call this%copy_to(dest, pack, copy_data, new_np, special, dest_type)
499 subroutine batch_clone_to_array(this, dest, n_batches, pack, copy_data, new_np, special, dest_type)
500 class(
batch_t),
intent(in) :: this
501 class(
batch_t),
allocatable,
intent(out) :: dest(:)
502 integer,
intent(in) :: n_batches
503 logical,
optional,
intent(in) :: pack
505 logical,
optional,
intent(in) :: copy_data
507 integer,
optional,
intent(in) :: new_np
508 logical,
optional,
intent(in) :: special
510 type(
type_t),
optional,
intent(in) :: dest_type
516 if (.not.
allocated(dest))
then
517 safe_allocate_type_array(
batch_t, dest, (1:n_batches))
519 message(1) =
"Internal error: destination batch in batch_clone_to_array has been previously allocated."
524 call this%copy_to(dest(ib), pack, copy_data, new_np, special, dest_type)
535 subroutine batch_copy_to(this, dest, pack, copy_data, new_np, special, dest_type)
536 class(
batch_t),
intent(in) :: this
537 class(
batch_t),
intent(out) :: dest
538 logical,
optional,
intent(in) :: pack
540 logical,
optional,
intent(in) :: copy_data
542 integer,
optional,
intent(in) :: new_np
543 logical,
optional,
intent(in) :: special
545 type(
type_t),
optional,
intent(in) :: dest_type
547 logical :: host_packed, special_
555 host_packed = this%host_buffer_count > 0
559 if (
present(special))
then
560 special_ = this%special_memory
562 special_ = this%special_memory .and. .not. this%device_buffer_count > 0
565 if (
present(dest_type))
then
572 call dbatch_init(dest, this%dim, 1, this%nst, np_, packed=host_packed, special=special_)
574 call zbatch_init(dest, this%dim, 1, this%nst, np_, packed=host_packed, special=special_)
576 call sbatch_init(dest, this%dim, 1, this%nst, np_, packed=host_packed, special=special_)
578 call cbatch_init(dest, this%dim, 1, this%nst, np_, packed=host_packed, special=special_)
580 message(1) =
"Internal error: unknown batch type in batch_copy_to."
584 if (this%status() /= dest%status() .and.
optional_default(pack, this%is_packed()))
call dest%do_pack(copy = .false.)
586 dest%ist_idim_index(1:this%nst_linear, 1:this%ndims) = this%ist_idim_index(1:this%nst_linear, 1:this%ndims)
587 dest%ist(1:this%nst) = this%ist(1:this%nst)
590 assert(np_ == this%np)
593 call this%copy_data_to(min(this%np, np_), dest)
604 type(
type_t)
pure function batch_type(this) result(btype)
605 class(
batch_t),
intent(in) :: this
613 integer pure function batch_type_as_integer(this) result(itype)
614 class(
batch_t),
intent(in) :: this
616 type(type_t) :: btype
620 if (btype == type_float) itype = 1
621 if (btype == type_cmplx) itype = 2
622 if (btype == type_float_single) itype = 3
623 if (btype == type_cmplx_single) itype = 4
632 integer pure function batch_status(this) result(bstatus)
633 class(
batch_t),
intent(in) :: this
635 bstatus = this%status_of
640 logical pure function batch_is_packed(this) result(in_buffer)
641 class(
batch_t),
intent(in) :: this
643 in_buffer = (this%device_buffer_count > 0) .or. (this%host_buffer_count > 0)
649 class(
batch_t),
intent(inout) :: this
652 if (accel_is_enabled())
size = accel_padded_size(size)
653 size = size*pad_pow2(this%nst_linear)*types_get_size(this%type())
665 class(
batch_t),
intent(inout) :: this
666 logical,
optional,
intent(in) :: copy
667 logical,
optional,
intent(in) :: async
670 integer :: source, target
675 source = this%status()
678 if (accel_is_enabled())
then
687 call this%do_pack(
target, copy, async)
696 class(
batch_t),
intent(inout) :: this
697 integer,
intent(in) ::
target
698 logical,
optional,
intent(in) :: copy
699 logical,
optional,
intent(in) :: async
701 logical,
optional,
intent(in) :: cpu_only
709 call profiling_in(
"BATCH_DO_PACK")
711 copy_ = optional_default(copy, .
true.)
713 async_ = optional_default(async, .false.)
716 source = this%status()
719 if (source /=
target)
then
722 call this%allocate_packed_device()
736 call this%allocate_packed_host()
741 if (this%type() == type_float)
then
743 else if (this%type() == type_cmplx)
then
745 else if (this%type() == type_float_single)
then
747 else if (this%type() == type_cmplx_single)
then
751 if (this%own_memory)
call this%deallocate_unpacked_host()
753 call messages_not_implemented(
"Error: batch_do_pack called with BATCH_NOT_PACKED as target.")
759 this%device_buffer_count = this%device_buffer_count + 1
761 this%host_buffer_count = this%host_buffer_count + 1
764 call profiling_out(
"BATCH_DO_PACK")
774 class(
batch_t),
intent(inout) :: this
775 logical,
optional,
intent(in) :: copy
776 logical,
optional,
intent(in) :: force
777 logical,
optional,
intent(in) :: async
780 logical :: copy_, force_, async_
781 integer :: source, target
785 call profiling_in(
"BATCH_DO_UNPACK")
787 copy_ = optional_default(copy, .
true.)
789 force_ = optional_default(force, .false.)
791 async_ = optional_default(async, .false.)
794 source = this%status()
801 target = this%status_host
805 if (source /=
target)
then
808 if (this%host_buffer_count == 1 .or. force_)
then
809 if (this%own_memory)
call this%allocate_unpacked_host()
811 if (copy_ .or. this%own_memory)
then
812 if (this%type() == type_float)
then
814 else if (this%type() == type_cmplx)
then
816 else if (this%type() == type_float_single)
then
818 else if (this%type() == type_cmplx_single)
then
822 call this%deallocate_packed_host()
823 this%status_host =
target
824 this%status_of =
target
825 this%host_buffer_count = 1
827 this%host_buffer_count = this%host_buffer_count - 1
829 if (this%device_buffer_count == 1 .or. force_)
then
841 this%needs_finish_unpack = .
true.
843 call this%deallocate_packed_device()
845 this%status_of =
target
846 this%device_buffer_count = 1
848 this%device_buffer_count = this%device_buffer_count - 1
852 call profiling_out(
"BATCH_DO_UNPACK")
860 class(
batch_t),
intent(inout) :: this
863 if (this%needs_finish_unpack)
then
865 call this%deallocate_packed_device()
866 this%needs_finish_unpack = .false.
874 class(
batch_t),
intent(inout) :: this
877 integer(int64) :: unroll, bsize, gsize
878 type(accel_mem_t) :: tmp
879 type(accel_kernel_t),
pointer :: kernel
883 call profiling_in(
"BATCH_WRT_UNPACK_ACCEL")
884 if (this%nst_linear == 1)
then
886 if (this%type() == type_float)
then
887 call accel_write_buffer(this%ff_device, ubound(this%dff_linear, dim=1), this%dff_linear(:, 1))
888 else if (this%type() == type_cmplx)
then
889 call accel_write_buffer(this%ff_device, ubound(this%zff_linear, dim=1), this%zff_linear(:, 1))
890 else if (this%type() == type_float_single)
then
891 call accel_write_buffer(this%ff_device, ubound(this%sff_linear, dim=1), this%sff_linear(:, 1))
893 call accel_write_buffer(this%ff_device, ubound(this%cff_linear, dim=1), this%cff_linear(:, 1))
899 if (this%type() == type_float)
then
901 else if (this%type() == type_cmplx)
then
903 else if (this%type() == type_float_single)
then
911 call accel_create_buffer(tmp, accel_mem_read_only, this%type(), unroll*this%pack_size(2))
913 do ist = 1, this%nst_linear, int(unroll, int32)
916 do ist2 = ist, min(ist + int(unroll, int32) - 1, this%nst_linear)
918 if (this%type() == type_float)
then
919 call accel_write_buffer(tmp, ubound(this%dff_linear, dim=1, kind=int64), this%dff_linear(:, ist2), &
920 offset = (ist2 - ist)*this%pack_size(2))
921 else if (this%type() == type_cmplx)
then
922 call accel_write_buffer(tmp, ubound(this%zff_linear, dim=1, kind=int64), this%zff_linear(:, ist2), &
923 offset = (ist2 - ist)*this%pack_size(2))
924 else if (this%type() == type_float_single)
then
925 call accel_write_buffer(tmp, ubound(this%sff_linear, dim=1, kind=int64), this%sff_linear(:, ist2), &
926 offset = (ist2 - ist)*this%pack_size(2))
928 call accel_write_buffer(tmp, ubound(this%cff_linear, dim=1, kind=int64), this%cff_linear(:, ist2), &
929 offset = (ist2 - ist)*this%pack_size(2))
934 call accel_set_kernel_arg(kernel, 0, int(this%pack_size(1), int32))
935 call accel_set_kernel_arg(kernel, 1, this%np)
936 call accel_set_kernel_arg(kernel, 2, this%nst_linear)
937 call accel_set_kernel_arg(kernel, 3, ist - 1)
938 call accel_set_kernel_arg(kernel, 4, tmp)
939 call accel_set_kernel_arg(kernel, 5, this%ff_device)
941 call profiling_in(
"GPU_PACK")
944 bsize = accel_max_block_size()/unroll
945 call accel_grid_size(this%pack_size(2), bsize, gsize)
947 call accel_kernel_run(kernel, (/gsize, 1_int64/), (/bsize, unroll/))
949 if (this%type() == type_float)
then
950 call profiling_count_transfers(unroll*this%pack_size(2), m_one)
952 call profiling_count_transfers(unroll*this%pack_size(2), m_zi)
956 call profiling_out(
"GPU_PACK")
960 call accel_free_buffer(tmp)
964 call profiling_out(
"BATCH_WRT_UNPACK_ACCEL")
971 class(
batch_t),
intent(inout) :: this
974 integer(int64) :: unroll, bsize, gsize
975 type(accel_mem_t) :: tmp
976 type(accel_kernel_t),
pointer :: kernel
979 call profiling_in(
"BATCH_READ_UNPACKED_ACCEL")
981 if (this%nst_linear == 1)
then
983 if (this%type() == type_float)
then
984 call accel_read_buffer(this%ff_device, ubound(this%dff_linear, dim=1), this%dff_linear(:, 1))
985 else if (this%type() == type_cmplx)
then
986 call accel_read_buffer(this%ff_device, ubound(this%zff_linear, dim=1), this%zff_linear(:, 1))
987 else if (this%type() == type_float_single)
then
988 call accel_read_buffer(this%ff_device, ubound(this%sff_linear, dim=1), this%sff_linear(:, 1))
990 call accel_read_buffer(this%ff_device, ubound(this%cff_linear, dim=1), this%cff_linear(:, 1))
997 call accel_create_buffer(tmp, accel_mem_write_only, this%type(), unroll*this%pack_size(2))
999 if (this%type() == type_float)
then
1001 else if (this%type() == type_cmplx)
then
1003 else if (this%type() == type_float_single)
then
1009 do ist = 1, this%nst_linear, int(unroll, int32)
1010 call accel_set_kernel_arg(kernel, 0, int(this%pack_size(1), int32))
1011 call accel_set_kernel_arg(kernel, 1, this%np)
1012 call accel_set_kernel_arg(kernel, 2, this%nst_linear)
1013 call accel_set_kernel_arg(kernel, 3, ist - 1)
1014 call accel_set_kernel_arg(kernel, 4, this%ff_device)
1015 call accel_set_kernel_arg(kernel, 5, tmp)
1017 call profiling_in(
"GPU_UNPACK")
1020 bsize = accel_max_block_size()/unroll
1021 call accel_grid_size(this%pack_size(2), bsize, gsize)
1023 call accel_kernel_run(kernel, (/1_int64, gsize/), (/unroll, bsize/))
1025 if (this%type() == type_float)
then
1026 call profiling_count_transfers(unroll*this%pack_size(2), m_one)
1028 call profiling_count_transfers(unroll*this%pack_size(2), m_zi)
1032 call profiling_out(
"GPU_UNPACK")
1035 do ist2 = ist, min(ist + int(unroll, int32) - 1, this%nst_linear)
1037 if (this%type() == type_float)
then
1038 call accel_read_buffer(tmp, ubound(this%dff_linear, dim=1, kind=int64), this%dff_linear(:, ist2), &
1039 offset = (ist2 - ist)*this%pack_size(2))
1040 else if (this%type() == type_cmplx)
then
1041 call accel_read_buffer(tmp, ubound(this%zff_linear, dim=1, kind=int64), this%zff_linear(:, ist2), &
1042 offset = (ist2 - ist)*this%pack_size(2))
1043 else if (this%type() == type_float_single)
then
1044 call accel_read_buffer(tmp, ubound(this%sff_linear, dim=1, kind=int64), this%sff_linear(:, ist2), &
1045 offset = (ist2 - ist)*this%pack_size(2))
1047 call accel_read_buffer(tmp, ubound(this%cff_linear, dim=1, kind=int64), this%cff_linear(:, ist2), &
1048 offset = (ist2 - ist)*this%pack_size(2))
1054 call accel_free_buffer(tmp)
1057 call profiling_out(
"BATCH_READ_UNPACKED_ACCEL")
1063 class(
batch_t),
intent(inout) :: this
1064 logical,
optional,
intent(in) :: async
1069 call profiling_in(
"BATCH_WRITE_PACKED_ACCEL")
1070 if (this%type() == type_float)
then
1071 call accel_write_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%dff_pack, async=async)
1072 else if (this%type() == type_cmplx)
then
1073 call accel_write_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%zff_pack, async=async)
1074 else if (this%type() == type_float_single)
then
1075 call accel_write_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%sff_pack, async=async)
1077 call accel_write_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%cff_pack, async=async)
1079 call profiling_out(
"BATCH_WRITE_PACKED_ACCEL")
1086 class(
batch_t),
intent(inout) :: this
1087 logical,
optional,
intent(in) :: async
1092 call profiling_in(
"BATCH_READ_PACKED_ACCEL")
1093 if (this%type() == type_float)
then
1094 call accel_read_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%dff_pack, async=async)
1095 else if (this%type() == type_cmplx)
then
1096 call accel_read_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%zff_pack, async=async)
1097 else if (this%type() == type_float_single)
then
1098 call accel_read_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%sff_pack, async=async)
1100 call accel_read_buffer(this%ff_device, this%pack_size(1), this%pack_size(2), this%cff_pack, async=async)
1102 call profiling_out(
"BATCH_READ_PACKED_ACCEL")
1113 class(
batch_t),
intent(in) :: this
1114 integer,
intent(in) :: cind(:)
1116 do index = 1, this%nst_linear
1117 if (all(cind(1:this%ndims) == this%ist_idim_index(index, 1:this%ndims)))
exit
1120 assert(index <= this%nst_linear)
1129 integer pure function batch_ist_idim_to_linear(this, cind) result(index)
1130 class(
batch_t),
intent(in) :: this
1131 integer,
intent(in) :: cind(:)
1133 if (ubound(cind, dim = 1) == 1)
then
1136 index = (cind(1) - 1)*this%dim + cind(2)
1147 integer pure function batch_linear_to_ist(this, linear_index) result(ist)
1148 class(
batch_t),
intent(in) :: this
1149 integer,
intent(in) :: linear_index
1151 ist = this%ist_idim_index(linear_index, 1)
1159 class(
batch_t),
intent(in) :: this
1160 integer,
intent(in) :: linear_index
1162 idim = this%ist_idim_index(linear_index, 2)
1177 class(
batch_t),
intent(inout) :: this
1178 type(mpi_grp_t),
intent(in) :: mpi_grp
1179 type(mpi_win),
intent(out) :: rma_win
1183 if (mpi_grp%size > 1)
then
1185 assert(.not. accel_is_enabled())
1189 assert(int(product(this%pack_size)*types_get_size(this%type())) > 0)
1190 if (this%type() == type_cmplx)
then
1192 call mpi_win_create(this%zff_pack(1, 1), int(product(this%pack_size)*types_get_size(this%type()), mpi_address_kind), &
1193 types_get_size(this%type()), mpi_info_null, mpi_grp%comm, rma_win)
1195 else if (this%type() == type_float)
then
1197 call mpi_win_create(this%dff_pack(1, 1), int(product(this%pack_size)*types_get_size(this%type()), mpi_address_kind), &
1198 types_get_size(this%type()), mpi_info_null, mpi_grp%comm, rma_win)
1200 else if (this%type() == type_cmplx_single)
then
1202 call mpi_win_create(this%cff_pack(1, 1), int(product(this%pack_size)*types_get_size(this%type()), mpi_address_kind), &
1203 types_get_size(this%type()), mpi_info_null, mpi_grp%comm, rma_win)
1205 else if (this%type() == type_float_single)
then
1207 call mpi_win_create(this%sff_pack(1, 1), int(product(this%pack_size)*types_get_size(this%type()), mpi_address_kind), &
1208 types_get_size(this%type()), mpi_info_null, mpi_grp%comm, rma_win)
1211 message(1) =
"Internal error: unknown batch type in batch_remote_access_start."
1212 call messages_fatal(1)
1216 rma_win = mpi_win_null
1230 class(
batch_t),
intent(inout) :: this
1231 type(mpi_win),
intent(inout) :: rma_win
1235 if (rma_win /= mpi_win_null)
then
1237 call mpi_win_free(rma_win)
1239 call this%do_unpack()
1249 class(
batch_t),
intent(in) :: this
1250 integer,
intent(in) :: np
1251 class(
batch_t),
intent(inout) :: dest
1252 logical,
optional,
intent(in) :: async
1254 integer(int64),
dimension(3) :: gsizes, bsizes
1256 type(accel_kernel_t),
pointer :: kernel
1259 call profiling_in(
"BATCH_COPY_DATA_TO")
1262 call this%check_compatibility_with(dest, type_check=.false.)
1264 if (this%type() == dest%type())
then
1265 select case (this%status())
1269 if (type_is_single(this%type()))
then
1270 kernel => kernel_scopy
1272 kernel => kernel_copy
1274 call accel_set_kernel_arg(kernel, 0, np)
1275 call accel_set_kernel_arg(kernel, 1, this%ff_device)
1276 call accel_set_kernel_arg(kernel, 2,
log2(int(this%pack_size_real(1), int32)))
1277 call accel_set_kernel_arg(kernel, 3, dest%ff_device)
1278 call accel_set_kernel_arg(kernel, 4,
log2(int(dest%pack_size_real(1), int32)))
1281 call accel_grid_size_extend_dim(int(np, int64), dest%pack_size_real(1), gsizes, bsizes, kernel)
1283 call accel_kernel_run(kernel, gsizes, bsizes)
1285 if(.not. optional_default(async, .false.))
call accel_finish()
1288 if (dest%type() == type_float_single)
then
1291 do ist = 1, int(this%pack_size(1), int32)
1292 dest%sff_pack(ist, ip) = this%sff_pack(ist, ip)
1295 else if (dest%type() == type_cmplx_single)
then
1298 do ist = 1, int(this%pack_size(1), int32)
1299 dest%cff_pack(ist, ip) = this%cff_pack(ist, ip)
1302 else if (np*this%pack_size(1) > huge(0_int32))
then
1305 if (dest%type() == type_float)
then
1306 call blas_copy(int(this%pack_size(1), int32), this%dff_pack(1, ip), 1, dest%dff_pack(1, ip), 1)
1308 call blas_copy(int(this%pack_size(1), int32), this%zff_pack(1, ip), 1, dest%zff_pack(1, ip), 1)
1312 if (dest%type() == type_float)
then
1313 call blas_copy(int(this%pack_size(1)*np, int32), this%dff_pack(1, 1), 1, dest%dff_pack(1, 1), 1)
1315 call blas_copy(int(this%pack_size(1)*np, int32), this%zff_pack(1, 1), 1, dest%zff_pack(1, 1), 1)
1320 do ist = 1, dest%nst_linear
1321 if (dest%type() == type_cmplx)
then
1322 call blas_copy(np, this%zff_linear(1, ist), 1, dest%zff_linear(1, ist), 1)
1323 else if (dest%type() == type_float_single)
then
1326 dest%sff_linear(ip, ist) = this%sff_linear(ip, ist)
1328 else if (dest%type() == type_cmplx_single)
then
1331 dest%cff_linear(ip, ist) = this%cff_linear(ip, ist)
1334 call blas_copy(np, this%dff_linear(1, ist), 1, dest%dff_linear(1, ist), 1)
1339 else if (this%type() == type_cmplx)
then
1341 select case (this%status())
1343 call accel_set_kernel_arg(kernel_copy_complex_to_real, 0, np)
1344 call accel_set_kernel_arg(kernel_copy_complex_to_real, 1, this%ff_device)
1345 call accel_set_kernel_arg(kernel_copy_complex_to_real, 2,
log2(int(this%pack_size_real(1), int32)))
1346 call accel_set_kernel_arg(kernel_copy_complex_to_real, 3, dest%ff_device)
1347 call accel_set_kernel_arg(kernel_copy_complex_to_real, 4,
log2(int(dest%pack_size_real(1), int32)))
1350 call accel_grid_size_extend_dim(int(np, int64), dest%pack_size_real(1), gsizes, bsizes, kernel_copy_complex_to_real)
1352 call accel_kernel_run(kernel_copy_complex_to_real, gsizes, bsizes)
1354 if(.not. optional_default(async, .false.))
call accel_finish()
1360 do ist = 1, dest%nst_linear
1361 dest%dff_pack(ist, ip) = real(this%zff_pack(ist, ip), real64)
1367 do ist = 1, dest%nst_linear
1370 dest%dff_linear(ip, ist) = real(this%zff_linear(ip, ist), real64)
1376 else if (this%type() == type_float)
then
1378 select case (this%status())
1380 call accel_set_kernel_arg(kernel_copy_real_to_complex, 0, np)
1381 call accel_set_kernel_arg(kernel_copy_real_to_complex, 1, this%ff_device)
1382 call accel_set_kernel_arg(kernel_copy_real_to_complex, 2,
log2(int(this%pack_size_real(1), int32)))
1383 call accel_set_kernel_arg(kernel_copy_real_to_complex, 3, dest%ff_device)
1384 call accel_set_kernel_arg(kernel_copy_real_to_complex, 4,
log2(int(dest%pack_size_real(1), int32)))
1387 call accel_grid_size_extend_dim(int(np, int64), this%pack_size_real(1), gsizes, bsizes, kernel_copy_real_to_complex)
1389 call accel_kernel_run(kernel_copy_real_to_complex, gsizes, bsizes)
1391 if(.not. optional_default(async, .false.))
call accel_finish()
1397 do ist = 1, dest%nst_linear
1398 dest%zff_pack(ist, ip) = cmplx(this%dff_pack(ist, ip), m_zero, real64)
1404 do ist = 1, dest%nst_linear
1407 dest%zff_linear(ip, ist) = cmplx(this%dff_linear(ip, ist), m_zero, real64)
1414 message(1) =
"Error! This should not happen."
1415 call messages_fatal(1)
1418 call profiling_out(
"BATCH_COPY_DATA_TO")
1426 class(
batch_t),
intent(in) :: this
1427 class(
batch_t),
intent(in) :: target
1428 logical,
optional,
intent(in) :: only_check_dim
1429 logical,
optional,
intent(in) :: type_check
1433 if (optional_default(type_check, .
true.))
then
1434 assert(this%type() ==
target%type())
1436 if (.not. optional_default(only_check_dim, .false.))
then
1437 assert(this%nst_linear ==
target%nst_linear)
1439 assert(this%status() ==
target%status())
1440 assert(this%dim ==
target%dim)
1450 class(
batch_t),
intent(inout) :: this
1451 integer,
intent(in) :: st_start
1452 integer,
intent(in) :: st_end
1454 integer :: idim, ii, ist
1458 do ist = st_start, st_end
1460 do idim = 1, this%dim
1461 ii = this%dim*(ist - st_start) + idim
1462 this%ist_idim_index(ii, 1) = ist
1463 this%ist_idim_index(ii, 2) = idim
1465 this%ist(ist - st_start + 1) = ist
1469 this%pack_size(1) = pad_pow2(this%nst_linear)
1470 this%pack_size(2) = this%np
1471 if (accel_is_enabled()) this%pack_size(2) = accel_padded_size(this%pack_size(2))
1473 this%pack_size_real = this%pack_size
1474 if (type_is_complex(this%type())) this%pack_size_real(1) = 2*this%pack_size_real(1)
1481#include "batch_inc.F90"
1484#include "complex.F90"
1485#include "batch_inc.F90"
1488#include "real32.F90"
1489#include "batch_inc.F90"
1492#include "complex32.F90"
1493#include "batch_inc.F90"
initialize a batch with existing memory
double log2(double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
integer, parameter, public accel_mem_read_write
This module contains interfaces for routines in allocate_hardware_aware.c.
subroutine, public deallocate_hardware_aware(array, size)
This module implements batches of mesh functions.
type(type_t) pure function batch_type(this)
return the type of a batch
subroutine zbatch_pack_copy(this)
copy data from the unpacked to the packed arrays
subroutine cbatch_init_with_memory_3(this, dim, st_start, st_end, psi)
initialize a batch with an rank-3 array of TYPE_CMPLX_SINGLE valued mesh functions psi.
subroutine, public batch_write_packed_to_device(this, async)
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
subroutine zbatch_init_with_memory_3(this, dim, st_start, st_end, psi)
initialize a batch with an rank-3 array of TYPE_CMPLX valued mesh functions psi.
subroutine batch_check_compatibility_with(this, target, only_check_dim, type_check)
check whether two batches have compatible dimensions (and type)
logical pure function batch_is_packed(this)
subroutine dbatch_unpack_copy(this)
copy data from the packed to the unpacked arrays
subroutine cbatch_pack_copy(this)
copy data from the unpacked to the packed arrays
subroutine dbatch_init_with_memory_1(this, psi)
initialize a batch with an rank-1 array of TYPE_FLOAT valued mesh functions psi.
subroutine cbatch_init_with_memory_2(this, dim, st_start, st_end, psi)
initialize a batch with an rank-2 array of TYPE_CMPLX_SINGLE valued mesh functions psi.
subroutine batch_write_unpacked_to_device(this)
subroutine batch_do_unpack(this, copy, force, async)
unpack a batch
subroutine batch_finish_unpack(this)
finish the unpacking if do_unpack() was called with async=.true.
subroutine zbatch_allocate_unpacked_host(this)
allocate host (CPU) memory for unpacked data of type TYPE_CMPLX
subroutine batch_deallocate_packed_device(this)
release packed device memory
integer pure function batch_type_as_integer(this)
For debuging purpose only.
subroutine sbatch_unpack_copy(this)
copy data from the packed to the unpacked arrays
subroutine batch_do_pack_generic(this, copy, async)
pack the data in a batch
integer function batch_inv_index(this, cind)
inverse index lookup
subroutine dbatch_init_with_memory_2(this, dim, st_start, st_end, psi)
initialize a batch with an rank-2 array of TYPE_FLOAT valued mesh functions psi.
subroutine batch_allocate_packed_host(this)
allocate host (CPU) memory for packed data
subroutine, public zbatch_init(this, dim, st_start, st_end, np, special, packed)
initialize a TYPE_CMPLX valued batch to given size without providing external memory
subroutine zbatch_allocate_packed_host(this)
allocate host (CPU) memory for packed data of type TYPE_CMPLX
subroutine batch_clone_to(this, dest, pack, copy_data, new_np, special, dest_type)
clone a batch to a new batch
subroutine cbatch_allocate_unpacked_host(this)
allocate host (CPU) memory for unpacked data of type TYPE_CMPLX_SINGLE
subroutine batch_remote_access_stop(this, rma_win)
stop the remote access to the batch
subroutine sbatch_allocate_unpacked_host(this)
allocate host (CPU) memory for unpacked data of type TYPE_FLOAT_SINGLE
subroutine batch_read_device_to_unpacked(this)
subroutine zbatch_init_with_memory_1(this, psi)
initialize a batch with an rank-1 array of TYPE_CMPLX valued mesh functions psi.
subroutine, public sbatch_init(this, dim, st_start, st_end, np, special, packed)
initialize a TYPE_FLOAT_SINGLE valued batch to given size without providing external memory
subroutine sbatch_pack_copy(this)
copy data from the unpacked to the packed arrays
subroutine dbatch_allocate_packed_host(this)
allocate host (CPU) memory for packed data of type TYPE_FLOAT
subroutine batch_clone_to_array(this, dest, n_batches, pack, copy_data, new_np, special, dest_type)
subroutine batch_allocate_packed_device(this)
allocate device (GPU) memory for packed data
subroutine batch_build_indices(this, st_start, st_end)
build the index ist(:) and ist_idim_index(:,:) and set pack_size
integer pure function batch_ist_idim_to_linear(this, cind)
direct index lookup
integer, parameter gpu_pack_max_buffer_size
this value controls the size (in number of wave-functions) of the buffer used to copy states to the G...
subroutine batch_do_pack_target(this, target, copy, async, cpu_only)
pack the data in a batch
subroutine sbatch_init_with_memory_1(this, psi)
initialize a batch with an rank-1 array of TYPE_FLOAT_SINGLE valued mesh functions psi.
integer pure function batch_linear_to_ist(this, linear_index)
get state index ist from linear (combined dim and nst) index
subroutine batch_copy_to(this, dest, pack, copy_data, new_np, special, dest_type)
make a copy of a batch
subroutine, public batch_read_device_to_packed(this, async)
subroutine cbatch_unpack_copy(this)
copy data from the packed to the unpacked arrays
subroutine dbatch_init_with_memory_3(this, dim, st_start, st_end, psi)
initialize a batch with an rank-3 array of TYPE_FLOAT valued mesh functions psi.
subroutine cbatch_init_with_memory_1(this, psi)
initialize a batch with an rank-1 array of TYPE_CMPLX_SINGLE valued mesh functions psi.
subroutine batch_allocate_unpacked_host(this)
allocate host (CPU) memory for unpacked data
subroutine, public cbatch_init(this, dim, st_start, st_end, np, special, packed)
initialize a TYPE_CMPLX_SINGLE valued batch to given size without providing external memory
subroutine batch_init_empty(this, dim, nst, np)
initialize an empty batch
subroutine, public dbatch_init(this, dim, st_start, st_end, np, special, packed)
initialize a TYPE_FLOAT valued batch to given size without providing external memory
subroutine zbatch_init_with_memory_2(this, dim, st_start, st_end, psi)
initialize a batch with an rank-2 array of TYPE_CMPLX valued mesh functions psi.
integer pure function batch_linear_to_idim(this, linear_index)
extract idim from linear index
subroutine batch_remote_access_start(this, mpi_grp, rma_win)
start remote access to a batch on another node
subroutine sbatch_allocate_packed_host(this)
allocate host (CPU) memory for packed data of type TYPE_FLOAT_SINGLE
subroutine batch_copy_data_to(this, np, dest, async)
copy data to another batch.
subroutine dbatch_allocate_unpacked_host(this)
allocate host (CPU) memory for unpacked data of type TYPE_FLOAT
subroutine dbatch_pack_copy(this)
copy data from the unpacked to the packed arrays
subroutine cbatch_allocate_packed_host(this)
allocate host (CPU) memory for packed data of type TYPE_CMPLX_SINGLE
subroutine sbatch_init_with_memory_2(this, dim, st_start, st_end, psi)
initialize a batch with an rank-2 array of TYPE_FLOAT_SINGLE valued mesh functions psi.
subroutine sbatch_init_with_memory_3(this, dim, st_start, st_end, psi)
initialize a batch with an rank-3 array of TYPE_FLOAT_SINGLE valued mesh functions psi.
integer pure function batch_status(this)
return the status of a batch
subroutine batch_deallocate_unpacked_host(this)
release unpacked host memory
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
subroutine batch_deallocate_packed_host(this)
release packed host memory
integer(int64) function batch_pack_total_size(this)
subroutine batch_end(this, copy)
finalize a batch and release allocated memory, if necessary
subroutine zbatch_unpack_copy(this)
copy data from the packed to the unpacked arrays
This module contains interfaces for BLAS routines You should not use these routines directly....
This module is intended to contain "only mathematical" functions and procedures.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
type(type_t), parameter, public type_cmplx_single
type(type_t), parameter, public type_float_single
type(type_t), parameter, public type_cmplx
type(type_t), parameter, public type_float
logical pure function, public type_is_single(this)
type(type_t), parameter, public type_none
Class defining batches of mesh functions.