In many situations, we need to perform the same operations over many mesh functions, such as the electronic wave functions.
It is therefore advantageous to group those functions into one object. This can ensure that different mesh functions are contiguous in memory.
Due to the nature of stencil operations, which constitute a large part of the low level operations on mesh functions, it is often more efficient to perform the same stencil operation over different mesh functions (i.e. using the state index as fast index), than looping first over the mesh index, which would, in general, require a different stencil for each mesh point. This is, in particular, the case for calculations utilizing GPUs.
Therefore, we store mesh functions in linear or in so-called packed form. The former refers to the ‘natural’ ordering where the mesh index is the fastest moving, while the latter is transposed.
The abstract class batch_t is the parent class for batches, such as electronic wave functions.
Definition of "batch_t"
type batch_tprivate
integer,public::nstinteger,public::dim
integer::npinteger::ndimsinteger,allocatable::ist_idim_index(:,:)integer,allocatable,public::ist(:)logical::is_allocatedlogical::own_memory!< does the batch own the memory or is it foreign memory?
!> We also need a linear array with the states in order to calculate derivatives, etc.
integer,public::nst_linear!< nst_linear = nst*std%dim
integer::status_ofinteger::status_hosttype(type_t)::type_of!< either TYPE_FLOAT or TYPE_COMPLEX
integer::device_buffer_count!< whether there is a copy in the opencl buffer
integer::host_buffer_count!< whether the batch was packed on the cpu
logical::special_memorylogical::needs_finish_unpack!> unpacked variables; linear variables are pointers with different shapes
FLOAT,pointer,contiguous,public::dff(:,:,:)CMPLX,pointer,contiguous,public::zff(:,:,:)FLOAT,pointer,contiguous,public::dff_linear(:,:)CMPLX,pointer,contiguous,public::zff_linear(:,:)!> packed variables; only rank-2 arrays due to padding to powers of 2
FLOAT,pointer,contiguous,public::dff_pack(:,:)CMPLX,pointer,contiguous,public::zff_pack(:,:)integer(i8),public::pack_size(1:2)integer(i8),public::pack_size_real(1:2)!< pack_size_real = pack_size; if batch type is complex, then pack_size_real(1) = 2*pack_size(1)
type(accel_mem_t),public::ff_devicecontains
procedure::check_compatibility_with=>batch_check_compatibility_withprocedure::clone_to=>batch_clone_toprocedure::clone_to_array=>batch_clone_to_arrayprocedure::copy_to=>batch_copy_toprocedure::copy_data_to=>batch_copy_data_toprocedure::do_pack=>batch_do_packprocedure::do_unpack=>batch_do_unpackprocedure::finish_unpack=>batch_finish_unpackprocedure::end=>batch_endprocedure::inv_index=>batch_inv_indexprocedure::is_packed=>batch_is_packedprocedure::ist_idim_to_linear=>batch_ist_idim_to_linearprocedure::linear_to_idim=>batch_linear_to_idimprocedure::linear_to_ist=>batch_linear_to_istprocedure::pack_total_size=>batch_pack_total_sizeprocedure::remote_access_start=>batch_remote_access_startprocedure::remote_access_stop=>batch_remote_access_stopprocedure::status=>batch_statusprocedure::type=>batch_typeprocedure::type_as_int=>batch_type_as_integerprocedure,private::dallocate_unpacked_host=>dbatch_allocate_unpacked_hostprocedure,private::zallocate_unpacked_host=>zbatch_allocate_unpacked_hostprocedure,private::allocate_unpacked_host=>batch_allocate_unpacked_hostprocedure,private::dallocate_packed_host=>dbatch_allocate_packed_hostprocedure,private::zallocate_packed_host=>zbatch_allocate_packed_hostprocedure,private::allocate_packed_host=>batch_allocate_packed_hostprocedure,private::allocate_packed_device=>batch_allocate_packed_deviceprocedure,private::deallocate_unpacked_host=>batch_deallocate_unpacked_hostprocedure,private::deallocate_packed_host=>batch_deallocate_packed_hostprocedure,private::deallocate_packed_device=>batch_deallocate_packed_deviceend type batch_t
This class includes information about the dimensions of the functions (number of states, spatial dimension and number of mesh points), but also internal book-keeping variables,
keeping track of the status of the batch. Furthermore, the batch_t data type contains pointers to the actual data arrays, and defines the methods for interacting with a batch.
Empty batches can be initialized with:
Initializing empty batches
subroutine X(batch_init)(this,dim,st_start,st_end,np,special,packed)class(batch_t),intent(inout)::thisinteger,intent(in)::dim
integer,intent(in)::st_startinteger,intent(in)::st_endinteger,intent(in)::nplogical,optional,intent(in)::special!< If .true., the allocation will be handled in C (to use pinned memory for GPUs)
logical,optional,intent(in)::packed!< If .true., the allocation will be handled in C (to use pinned memory for GPUs)
PUSH_SUB(X(batch_init))call batch_init_empty(this,dim,st_end-st_start+1,np)this%special_memory=optional_default(special,.false.)this%type_of=R_TYPE_VALcall batch_build_indices(this,st_start,st_end)if(optional_default(packed,.false.))then
call this%X(allocate_packed_host)()this%status_of=BATCH_PACKEDthis%status_host=BATCH_PACKEDthis%host_buffer_count=this%host_buffer_count+1else
call this%X(allocate_unpacked_host)()end if
this%own_memory=.true.POP_SUB(X(batch_init))end subroutine X(batch_init)
type,extends(batch_t)::wfs_elec_tprivate
integer,public::iklogical,public::has_phasecontains
procedure::clone_to=>wfs_elec_clone_toprocedure::clone_to_array=>wfs_elec_clone_to_arrayprocedure::copy_to=>wfs_elec_copy_toprocedure::check_compatibility_with=>wfs_elec_check_compatibility_withprocedure::end=>wfs_elec_endend type wfs_elec_t