TABLE OF CONTENTS
- 1. CASUP/ca_hx
- 1.1. ca_hx/ca_halloc
- 1.2. ca_hx/ca_hdalloc
- 1.3. ca_hx/ca_hx_1D
- 1.3.1. ca_hx_1D/ca_1D_halloc
- 1.3.2. ca_hx_1D/ca_1D_hdalloc
- 1.3.3. ca_hx_1D/ca_1D_hx_check
- 1.3.4. ca_hx_1D/ca_1D_hx_sall
- 1.4. ca_hx/ca_hx_all
- 1.5. ca_hx/ca_hx_check
- 1.6. ca_hx/ca_hx_co
- 1.6.1. ca_hx_co/ca_co_hx_all
- 1.6.2. ca_hx_co/ca_co_hx_check
- 1.6.3. ca_hx_co/ca_co_ising_energy
- 1.6.4. ca_hx_co/ca_co_naive_io
- 1.6.5. ca_hx_co/ca_co_netcdf
- 1.6.6. ca_hx_co/ca_co_run
- 1.6.7. ca_hx_co/ca_co_spalloc
- 1.7. ca_hx/ca_hx_glbar
- 1.8. ca_hx/ca_hx_mpi
- 1.8.1. ca_hx_mpi/ca_mpi_halo_type_create
- 1.8.2. ca_hx_mpi/ca_mpi_halo_type_free
- 1.8.3. ca_hx_mpi/ca_mpi_hx_all
- 1.8.4. ca_hx_mpi/ca_mpi_hxvn1m
- 1.8.5. ca_hx_mpi/ca_mpi_hxvn1p
- 1.8.6. ca_hx_mpi/ca_mpi_hxvn2m
- 1.8.7. ca_hx_mpi/ca_mpi_hxvn2p
- 1.8.8. ca_hx_mpi/ca_mpi_hxvn3m
- 1.8.9. ca_hx_mpi/ca_mpi_hxvn3p
- 1.8.10. ca_hx_mpi/ca_mpi_ising_energy
- 1.9. ca_hx/ca_ising_energy
- 1.10. ca_hx/ca_ising_energy_col
- 1.11. ca_hx/ca_iter_dc
- 1.12. ca_hx/ca_iter_omp
- 1.13. ca_hx/ca_iter_tl
- 1.14. ca_hx/ca_kernel_copy
- 1.15. ca_hx/ca_kernel_ising
- 1.16. ca_hx/ca_kernel_ising_ener
- 1.17. ca_hx/ca_run
- 1.18. ca_hx/ca_set_space_rnd
- 1.19. ca_hx/ca_spalloc
ca_hx/ca_halloc [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_halloc
SYNOPSIS
subroutine ca_halloc( ir )
INPUT
integer :: ir(3) ! ir - codimensions
OUTPUT
! none
SIDE EFFECTS
halo coarrays (module variables) are allocated
DESCRIPTION
This routine allocates 6 halo coarrays for von Neumann 6-neighbourhood. The coarrays are module variables. Coarray allocation is an implicit sync. Halos have depth hdepth. Halo coarrays have the same cobounds on all images.
NOTES
All images must call this routine!
USES
USED BY
SOURCE
integer :: i,j,k main: associate( do => hdepth, c => sub ) if ( this_image() .eq. 1 ) write (*,*) "halloc: d:", do, "c:", c allocate( h1minu( do, c(2), c(3) ) [ ir(1), ir(2), * ], stat=ierr, & errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_halloc: allocate( h1minu ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if allocate( h1plus( do, c(2), c(3) ) [ ir(1), ir(2), * ], stat=ierr, & errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_halloc: allocate( h1plus ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if allocate( h2minu( c(1), do, c(3) ) [ ir(1), ir(2), * ], stat=ierr, & errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_halloc: allocate( h2minu ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if allocate( h2plus( c(1), do, c(3) ) [ ir(1), ir(2), * ], stat=ierr, & errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_halloc: allocate( h2plus ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if allocate( h3minu( c(1), c(2), do ) [ ir(1), ir(2), * ], stat=ierr, & errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_halloc: allocate( h3minu ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if allocate( h3plus( c(1), c(2), do ) [ ir(1), ir(2), * ], stat=ierr, & errmsg=errmsg) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_halloc: allocate( h3plus ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if ! Calculate once and keep forever ci = this_image( h1minu ) ucob = ucobound( h1minu ) ! Now can set mask_array. The mask array must reflect ! the global CA space, i.e. must not be affected by partitioning ! of the model into images. This means the mask array must ! depend on coindex set of this image. do concurrent( i=1:c(1), j=1:c(2), k=1:c(3) ) mask_array(i,j,k) = int( mod( (i+j+k + ( ci(1)-1)*c(1) + & (ci(2)-1)*c(2) + (ci(3)-1)*c(3) ) , 2 ), kind=iarr ) end do end associate main ! Calculate coindex sets and image numbers for the 6 neighbours ! Coindex sets nei_ci_L1 = (/ ci(1)-1, ci(2), ci(3) /) nei_ci_R1 = (/ ci(1)+1, ci(2), ci(3) /) nei_ci_L2 = (/ ci(1), ci(2)-1, ci(3) /) nei_ci_R2 = (/ ci(1), ci(2)+1, ci(3) /) nei_ci_L3 = (/ ci(1), ci(2), ci(3)-1 /) nei_ci_R3 = (/ ci(1), ci(2), ci(3)+1 /) ! Image index nei_img_L(1) = image_index( h1plus, nei_ci_L1 ) nei_img_R(1) = image_index( h1plus, nei_ci_R1 ) nei_img_L(2) = image_index( h1plus, nei_ci_L2 ) nei_img_R(2) = image_index( h1plus, nei_ci_R2 ) nei_img_L(3) = image_index( h1plus, nei_ci_L3 ) nei_img_R(3) = image_index( h1plus, nei_ci_R3 ) end subroutine ca_halloc
ca_hx/ca_hdalloc [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_hdalloc
SYNOPSIS
subroutine ca_hdalloc
INPUT
! none
OUTPUT
! none
SIDE EFFECTS
halo coarrays (module variables) are deallocated
DESCRIPTION
This routine deallocates 6 halo coarrays for von Neumann 6-neighbourhood. The coarrays are module variables. Coarray deallocation is an implicit sync. Halo coarrays have the same cobounds on all images.
NOTES
All images must call this routine!
USES
USED BY
SOURCE
deallocate( h1minu, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_hdalloc: deallocate( h1minu ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if deallocate( h1plus, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_hdalloc: deallocate( h1plus ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if deallocate( h2minu, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_hdalloc: deallocate( h2minu ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if deallocate( h2plus, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_hdalloc: deallocate( h2plus ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if deallocate( h3minu, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_hdalloc: deallocate( h3minu ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if deallocate( h3plus, stat=ierr, errmsg=errmsg) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_hdalloc: deallocate( h3plus ). ierr: ", & ierr, "errmsg:", trim(errmsg) error stop end if end subroutine ca_hdalloc
ca_hx/ca_hx_all [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_hx_all
SYNOPSIS
subroutine ca_hx_all( space )
INPUT
integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) ! space - non coarray array with CA model
OUTPUT
! none
SIDE EFFECTS
halo coarrays are updated
DESCRIPTION
HX is a 2-step process. In step 1 I copy parts of my space array, not space halos!, into my halo coarrays. Step 2 is remote comms - I pull neighbour halo coarrays into my local space array halo sections.
Important! the 6 routines must be called in the same order on all images to avoid deadlocks. So to make it fool proof I don't allow the user to call individual hx routines. These are private to this module. The user only calls this routine.
USES
USED BY
SOURCE
! HX is a 2-step process ! Step 1 ! I prepare my 6 coarray halos for use by my neighbours. ! These are copies of the slabs of space array, i.e. top/bottom, ! left/right and front/back. ! Note that these are not space array halos! ! Refer to the schematic in ca_spalloc for details. ! When done, I declare that my 6 coarray halos "ready" to be read - ! ready for remote calls. ! This is a local routine, which must be run before any ! of hx routines are called. ! This routine is called when all cells on my image have been ! processed, so doesn't make sense to separate separate assignments ! into different routines - no performance gain at all. if ( ci(1) .ne. 1 ) then h1minu(:,:,:) = space( 1 : hdepth , 1:sub(2) , 1:sub(3) ) end if if ( ci(1) .ne. ucob(1) ) then h1plus(:,:,:) = space( ihsta(1) : sub(1) , 1:sub(2) , 1:sub(3) ) end if if ( ci(2) .ne. 1 ) then h2minu(:,:,:) = space( 1:sub(1) , 1 : hdepth , 1:sub(3) ) end if if ( ci(2) .ne. ucob(2) ) then h2plus(:,:,:) = space( 1:sub(1) , ihsta(2) : sub(2) , 1:sub(3) ) end if if ( ci(3) .ne. 1 ) then h3minu(:,:,:) = space( 1:sub(1) , 1:sub(2) , 1 : hdepth ) end if if ( ci(3) .ne. ucob(3) ) then h3plus(:,:,:) = space( 1:sub(1) , 1:sub(2) , ihsta(3) : sub(3) ) end if ! Step 2 ! An image updates its space array halo layer (left side) ! along direction 1 from a coarray halo (h1plus) on an image ! which is 1 lower along codimension 1. if ( ci(1) .ne. 1 ) then sync images( nei_img_L(1) ) space( lhsta(1):0, 1:sub(2), 1:sub(3) ) = & h1plus(:,:,:) [ nei_ci_L1(1), nei_ci_L1(2), nei_ci_L1(3) ] end if ! An image updates its space array halo layer (right side) ! along direction 1 from a coarray halo (h1minu) on an image ! which is 1 higher along codimension 1. if ( ci(1) .ne. ucob(1) ) then sync images( nei_img_R(1) ) space( rhsta(1) : rhend(1), 1:sub(2) , 1:sub(3) ) = & h1minu(:,:,:) [ nei_ci_R1(1), nei_ci_R1(2), nei_ci_R1(3) ] end if ! An image updates its space array halo layer (left side) ! along direction 2 from a coarray halo (h1plus) on an image ! which is 1 lower along codimension 2. if ( ci(2) .ne. 1 ) then sync images( nei_img_L(2) ) space( 1:sub(1) , lhsta(2) : 0, 1:sub(3) ) = & h2plus(:,:,:) [ nei_ci_L2(1), nei_ci_L2(2), nei_ci_L2(3) ] end if ! An image updates its space array halo layer (right side) ! along direction 2 from a coarray halo (h2minu) on an image ! which is 1 higher along codimension 1. if ( ci(2) .ne. ucob(2) ) then sync images( nei_img_R(2) ) space( 1:sub(1) , rhsta(2) : rhend(2) , 1:sub(3) ) = & h2minu(:,:,:) [ nei_ci_R2(1), nei_ci_R2(2), nei_ci_R2(3) ] end if ! An image updates its space array halo layer (left side) ! along direction 3 from a coarray halo (h3plus) on an image ! which is 1 lower along codimension 3. if ( ci(3) .ne. 1 ) then sync images( nei_img_L(3) ) space( 1:sub(1) , 1:sub(2) , lhsta(3) : 0 ) = & h3plus(:,:,:) [ nei_ci_L3(1), nei_ci_L3(2), nei_ci_L3(3) ] end if ! An image updates its space array halo layer (right side) ! along direction 3 from a coarray halo (h3minu) on an image ! which is 1 higher along codimension 3. if ( ci(3) .ne. ucob(3) ) then sync images( nei_img_R(3) ) space( 1:sub(1) , 1:sub(2) , rhsta(3) : rhend(3) ) = & h3minu(:,:,:) [ nei_ci_R3(1), nei_ci_R3(2), nei_ci_R3(3) ] end if end subroutine ca_hx_all
ca_hx/ca_hx_check [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_hx_check
SYNOPSIS
subroutine ca_hx_check( space, flag )
INPUT
integer( kind=iarr ), intent(in), allocatable :: space(:,:,:) ! space - CA array
OUTPUT
integer, intent( out ) :: flag ! flag .eq. 0 - check passed ! flag .ne. 0 - check failed
SIDE EFFECTS
none
DESCRIPTION
This routine is of very limited use. It checks hx code for only a single case - all images set all their cell values to this_image() and then a single hx step is done. In this case I'm sure what's in my halos. So just check for this and either return flag=0 or flag > 0 indicating which halo failed. Fail values:
0 - pass, no failures 1 - test 1 failed 2 - test 2 failed 3 - tests 1,2 failed 4 - test 3 failed 5 - tests 1,3 failed 6 - tests 2,3 failed 7 - tests 1,2,3 failed 8 - test 4 failed 9 - tests 1,4 failed 10 - tests 2,4 failed 11 - tests 1,2,4 failed 12 - tests 3,4 failed 13 - tests 1,3,4 failed 14 - tests 2,3,4 failed 15 - tests 1,2,3,4 failed 16 - test 5 failed
and so on.
USES
USED BY
SOURCE
! coindex set and the image number of the neighbour integer :: i(3), n flag = 0 ! Test 1 if ( ci(1) .ne. 1 ) then ! This is the neighbour i = (/ ci(1)-1, ci(2), ci(3) /) ! neighbour's coindex set n = image_index( h1plus, i ) ! neighbour image number if ( any( space( lhsta(1):0, 1:sub(2), 1:sub(3) ) .ne. n ) ) & flag = flag + 1 end if ! Test 2 if ( ci(1) .ne. ucob(1) ) then ! This is the neighbour i = (/ ci(1)+1, ci(2), ci(3) /) ! neighbour's coindex set n = image_index( h1plus, i ) ! neighbour image number if ( any( space( rhsta(1):rhend(1), 1:sub(2), 1:sub(3) ) .ne. n ) ) & flag = flag + 2 end if ! Test 3 if ( ci(2) .ne. 1 ) then ! This is the neighbour i = (/ ci(1), ci(2)-1, ci(3) /) ! neighbour's coindex set n = image_index( h1plus, i ) ! neighbour image number if ( any( space( 1:sub(1), lhsta(2):0, 1:sub(3) ) .ne. n ) ) & flag = flag + 4 end if ! Test 4 if ( ci(2) .ne. ucob(2) ) then ! This is the neighbour i = (/ ci(1), ci(2)+1, ci(3) /) ! neighbour's coindex set n = image_index( h1plus, i ) ! neighbour image number if ( any( space( 1:sub(1), rhsta(2):rhend(2), 1:sub(3) ) .ne. n ) ) & flag = flag + 8 end if ! Test 5 if ( ci(3) .ne. 1 ) then ! This is the neighbour i = (/ ci(1), ci(2), ci(3)-1 /) ! neighbour's coindex set n = image_index( h1plus, i ) ! neighbour image number if ( any( space( 1:sub(1), 1:sub(2), lhsta(3):0 ) .ne. n ) ) & flag = flag + 16 end if ! Test 6 if ( ci(3) .ne. ucob(3) ) then ! This is the neighbour i = (/ ci(1), ci(2), ci(3)+1 /) ! neighbour's coindex set n = image_index( h1plus, i ) ! neighbour image number if ( any( space( 1:sub(1), 1:sub(2), rhsta(3):rhend(3) ) .ne. n ) ) & flag = flag + 32 end if end subroutine ca_hx_check
ca_hx/ca_hx_glbar [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_hx_glbar
SYNOPSIS
subroutine ca_hx_glbar( space )
INPUT
integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) ! space - non coarray array with CA model
OUTPUT
! none
SIDE EFFECTS
halo coarrays are updated
DESCRIPTION
The only difference from ca_hx_all is that here I use a global barrier (hence the name GL BAR), sync all.
USES
USED BY
SOURCE
if ( ci(1) .ne. 1 ) then h1minu(:,:,:) = space( 1 : hdepth , 1:sub(2) , 1:sub(3) ) end if if ( ci(1) .ne. ucob(1) ) then h1plus(:,:,:) = space( ihsta(1) : sub(1) , 1:sub(2) , 1:sub(3) ) end if if ( ci(2) .ne. 1 ) then h2minu(:,:,:) = space( 1:sub(1) , 1 : hdepth , 1:sub(3) ) end if if ( ci(2) .ne. ucob(2) ) then h2plus(:,:,:) = space( 1:sub(1) , ihsta(2) : sub(2) , 1:sub(3) ) end if if ( ci(3) .ne. 1 ) then h3minu(:,:,:) = space( 1:sub(1) , 1:sub(2) , 1 : hdepth ) end if if ( ci(3) .ne. ucob(3) ) then h3plus(:,:,:) = space( 1:sub(1) , 1:sub(2) , ihsta(3) : sub(3) ) end if sync all if ( ci(1) .ne. 1 ) then space( lhsta(1):0, 1:sub(2), 1:sub(3) ) = & h1plus(:,:,:) [ nei_ci_L1(1), nei_ci_L1(2), nei_ci_L1(3) ] end if if ( ci(1) .ne. ucob(1) ) then space( rhsta(1) : rhend(1), 1:sub(2) , 1:sub(3) ) = & h1minu(:,:,:) [ nei_ci_R1(1), nei_ci_R1(2), nei_ci_R1(3) ] end if if ( ci(2) .ne. 1 ) then space( 1:sub(1) , lhsta(2) : 0, 1:sub(3) ) = & h2plus(:,:,:) [ nei_ci_L2(1), nei_ci_L2(2), nei_ci_L2(3) ] end if if ( ci(2) .ne. ucob(2) ) then space( 1:sub(1) , rhsta(2) : rhend(2) , 1:sub(3) ) = & h2minu(:,:,:) [ nei_ci_R2(1), nei_ci_R2(2), nei_ci_R2(3) ] end if if ( ci(3) .ne. 1 ) then space( 1:sub(1) , 1:sub(2) , lhsta(3) : 0 ) = & h3plus(:,:,:) [ nei_ci_L3(1), nei_ci_L3(2), nei_ci_L3(3) ] end if if ( ci(3) .ne. ucob(3) ) then space( 1:sub(1) , 1:sub(2) , rhsta(3) : rhend(3) ) = & h3minu(:,:,:) [ nei_ci_R3(1), nei_ci_R3(2), nei_ci_R3(3) ] end if end subroutine ca_hx_glbar
ca_hx/ca_ising_energy [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_ising_energy
SYNOPSIS
subroutine ca_ising_energy( space, hx_sub, iter_sub, kernel, energy, & magnet )
INPUT
integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) procedure( hx_proto ) :: hx_sub procedure( iter_proto ) :: iter_sub procedure( kernel_proto ) :: kernel ! space - space array before iterations start ! iter_sub - the subroutine performing a single CA iteration, e.g. ! - ca_iter_tl - triple nested loop ! - ca_iter_dc - do concurrent ! - ca_iter_omp - OpenMP ! kernel - a function to be called for every cell inside the loop
OUTPUT
integer( kind=ilrg ), intent(out) :: energy, magnet ! energy - Total energy of CA system ! magnet - Total magnetisation of the CA system
SIDE EFFECTS
module array tmp_space is updated
DESCRIPTION
Calculate the total energy and the total magnetisation of CA using ising model. This routine does not use collectives. Magnetisation is defined as the fraction of the 1 spins. The only valid kernel is ca_kernel_ising_ener.
USES
USED BY
SOURCE
integer( kind=ilrg) :: my_energy, my_magnet co_energy = 0 co_magnet = 0 call hx_sub( space ) ! space updated, sync images call iter_sub( space, hdepth, kernel ) ! tmp_space updated, local op my_energy = & int( sum( tmp_space( 1:sub(1), 1:sub(2), 1:sub(3) ) ), kind=ilrg ) my_magnet = & int( sum( space( 1:sub(1), 1:sub(2), 1:sub(3) ) ), kind=ilrg ) !write (*,"(a,i0,a,999i3)") "img: ", this_image(), " tmp_space: ", tmp_space !write (*,*) "img:", this_image(), "my energy:", my_energy ! This is a tmp version on systems with no CO_SUM! ! Change on Cray! ! ! Image 1 calculates the total values in a *coarray* variable! critical co_energy[1] = co_energy[1] + my_energy co_magnet[1] = co_magnet[1] + my_magnet end critical ! I read the total values from image 1 ! Magnetisation is real value, scaled by the total number of ! cells in the global model. sync all energy = co_energy[1] magnet = co_magnet[1] ! Better do the scaling in the end user program. ! I want the routine to return an integer magnetisation ! so that the results can be exactly reproducible. !magnet = real( co_magnet[1] ) / real( total_cells ) end subroutine ca_ising_energy
ca_hx/ca_ising_energy_col [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_ising_energy_col
SYNOPSIS
subroutine ca_ising_energy_col( space, hx_sub, iter_sub, kernel, & energy, magnet)
INPUT
integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) procedure( hx_proto ) :: hx_sub procedure( iter_proto ) :: iter_sub procedure( kernel_proto ) :: kernel ! space - space array before iterations start ! hx_sub - ca_hx_all ! iter_sub - the subroutine performing a single CA iteration, e.g. ! - ca_iter_tl - triple nested loop ! - ca_iter_dc - do concurrent ! - ca_iter_omp - OpenMP ! kernel - a function to be called for every cell inside the loop
OUTPUT
integer( kind=ilrg ) , intent(out) :: energy, magnet ! energy - Total energy of CA system ! magnet - Total magnetisation of the CA system
SIDE EFFECTS
module array tmp_space is updated
DESCRIPTION
Calculate the total energy and the total magnetisation of CA using ising model. These integer values might be very large so I'm using a large integer kind (ilrg). This routine uses collectives. Magnetisation is defined as the fraction of the 1 spins. The only valid kernel is ca_kernel_ising_ener.
USES
USED BY
SOURCE
call hx_sub( space ) ! space updated, sync images call iter_sub( space, hdepth, kernel ) ! tmp_space updated, local op energy = & int( sum( tmp_space( 1:sub(1), 1:sub(2), 1:sub(3) ) ), kind=ilrg ) magnet = & int( sum( space( 1:sub(1), 1:sub(2), 1:sub(3) ) ), kind=ilrg ) call co_sum( energy ) call co_sum( magnet ) end subroutine ca_ising_energy_col
ca_hx/ca_iter_dc [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_iter_dc
SYNOPSIS
subroutine ca_iter_dc( space, halo, kernel )
INPUT
integer, intent( in ) :: halo integer( kind=iarr ), intent( in ), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) procedure( kernel_proto ) :: kernel ! space - CA array at the end of the previous iteration
OUTPUT
! none
SIDE EFFECTS
module array tmp_space, CA state at the end of this iteration, is updated
DESCRIPTION
This routine does a single CA iteration with DO CONCURRENT. The space array from the previous iteration is read only. The space array at the end of this iteration, tmp_space, from this module, is written only.
USES
USED BY
SOURCE
integer :: i, j, k ! Do not include halo! So start at 1 and end at sub. do concurrent( k = 1:sub(3), j = 1:sub(2), i = 1:sub(1) ) tmp_space( i,j,k ) = kernel( space = space, halo = hdepth, & coord = (/ i , j , k /) ) end do end subroutine ca_iter_dc
ca_hx/ca_iter_omp [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_iter_omp
SYNOPSIS
subroutine ca_iter_omp( space, halo, kernel )
INPUT
integer, intent( in ) :: halo integer( kind=iarr ), intent( in ), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) procedure( kernel_proto ) :: kernel ! space - CA array at the end of the previous iteration
OUTPUT
! none
SIDE EFFECTS
module array tmp_space, CA state at the end of this iteration, is updated
DESCRIPTION
This routine does a single CA iteration with triple nested loops. The space array from the previous iteration is read only. The space array at the end of this iteration, tmp_space, from this module, is written only.
USES
USED BY
SOURCE
integer :: i, j, k ! Do not include halo! So start at 1 and end at sub. !$omp parallel do default(none) & !$omp private(i,j,k) shared(sub,space,hdepth,tmp_space) ! !$omp collapse(3) do k = 1, sub(3) do j = 1, sub(2) do i = 1, sub(1) tmp_space( i,j,k ) = kernel( space = space, halo = hdepth, & coord = (/ i , j , k /) ) end do end do end do !$omp end parallel do end subroutine ca_iter_omp
ca_hx/ca_iter_tl [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_iter_tl
SYNOPSIS
subroutine ca_iter_tl( space, halo, kernel )
INPUT
integer, intent( in ) :: halo integer( kind=iarr ), intent( in ), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) procedure( kernel_proto ) :: kernel ! space - CA array at the end of the previous iteration
OUTPUT
! none
SIDE EFFECTS
module array tmp_space, CA state at the end of this iteration, is updated
DESCRIPTION
This routine does a single CA iteration with triple nested loops. The space array from the previous iteration is read only. The space array at the end of this iteration, tmp_space, from this module, is written only.
USES
USED BY
ca_run, ca_co_run, ca_ising_energy
SOURCE
integer :: i, j, k ! Do not include halo! So start at 1 and end at sub. do k = 1, sub(3) do j = 1, sub(2) do i = 1, sub(1) tmp_space( i,j,k ) = kernel( space = space, halo = hdepth, & coord = (/ i , j , k /) ) ! write (*, "(a,i0,a,4(i0,tr1))") & ! "img: ", this_image(), " i,j,k,energy: ", i, j, k, tmp_space(i,j,k) end do end do end do end subroutine ca_iter_tl
ca_hx/ca_kernel_copy [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_kernel_copy
SYNOPSIS
pure function ca_kernel_copy( space, halo, coord )
INPUTS
integer, intent( in ) :: halo integer( kind=iarr ), intent( in ), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) integer, intent(in) :: coord(3)
OUTPUT
integer( kind=iarr ) ca_kernel_copy
SIDE EFFECTS
None DESCIPTION This is a simplest CA kernel function. Simply copy the previous state of each cell. This function is used only to test the library.
USES
USED BY
SOURCE
ca_kernel_copy = space( coord(1), coord(2), coord(3) ) end function ca_kernel_copy
ca_hx/ca_kernel_ising [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_kernel_ising
SYNOPSIS
pure function ca_kernel_ising( space, halo, coord )
INPUTS
integer, intent( in ) :: halo integer( kind=iarr ), intent( in ), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) integer, intent( in ) :: coord(3)
OUTPUT
integer( kind=iarr ) ca_kernel_ising
SIDE EFFECTS
None DESCIPTION ising magnetisation CA kernel function. The CA state is magnetic spin, either 0 (down) or 1 (up). The sign of the spin (CA cell state) is changed if and only if this spin has the same number of parallel and anti-parallel neighbours, i.e. the sum of 6 neighbours is exactly 3 - three neighbours of spin up (3*1=3) and three neighbours of spin down (0). The multiplier alternates between 0 and 1 from one cell to the next. This preserves the energy. For more details see Sec. 2.2.3 "The Q2R rule" in: B. Chopard, M. Droz "Cellular Automata Modeling of Physical Systems", Cambridge, 1998.
USES
USED BY
ca_iter_tl, ca_iter_dc, ca_iter_omp, ca_run, ca_co_run
SOURCE
integer( kind=iarr ) :: n associate( s => space, i => coord(1), j => coord(2), k => coord(3) ) n = s(i-1,j,k) + s(i+1,j,k) + s(i,j-1,k) + s(i,j+1,k) + s(i,j,k-1) + & s(i,j,k+1) if ( n .eq. 3 .and. mask_array(i,j,k) .eq. 1 ) then ! If the sum of 6 neighbours is exactly 3 and the mask value is 1 ! then flip the state. ca_kernel_ising = 1_iarr - s(i,j,k) else ! Otherwise no change ca_kernel_ising = s(i,j,k) end if end associate end function ca_kernel_ising
ca_hx/ca_kernel_ising_ener [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_kernel_ising_ener
SYNOPSIS
pure function ca_kernel_ising_ener( space, halo, coord )
INPUTS
integer, intent( in ) :: halo integer( kind=iarr ), intent( in ), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) integer, intent( in ) :: coord(3)
OUTPUT
integer( kind=iarr ) ca_kernel_ising_ener
SIDE EFFECTS
None DESCIPTION ising magnetisation CA kernel function for energy calculation. Each neighbour of the same spin adds -1 to the energy. Each neighbour of the opposite spin adds +1 to the energy. For more details see Sec. 2.2.3 "The Q2R rule" in: B. Chopard, M. Droz, "Cellular Automata Modeling of Physical Systems", Cambridge, 1998.
To avoid double counting, each cell only checks links with cells to its *left* in all 3 dimensions. This leaves the last cells in the global CA space along each dimension, which must also look to the right, i.e. to the global right halo. This is not satisfactory because not all cells are processed in the same way. However, I cannot think of a better algorithm.
USES
USED BY
ca_iter_tl, ca_iter_dc, ca_iter_omp, ca_ising_energy
SOURCE
integer( kind=iarr ) :: count(6) count=0 associate( s => space, i => coord(1), j => coord(2), k => coord(3) ) ! s(i,j,k) - s(i-1,j,k) => 0, -1, 1 ! abs( s(i,j,k) - s(i-1,j,k) ) => 0, 1 ! 2 * abs( s(i,j,k) - s(i-1,j,k) ) => 0, 2 ! 2 * abs( s(i,j,k) - s(i-1,j,k) ) - 1 => -1, 1 ! Neighbours to the left along 3 directions count(1) = 2_iarr * abs( s(i,j,k) - s(i-1,j,k) ) - 1_iarr count(2) = 2_iarr * abs( s(i,j,k) - s(i,j-1,k) ) - 1_iarr count(3) = 2_iarr * abs( s(i,j,k) - s(i,j,k-1) ) - 1_iarr ! Neighbours to the right, only for the globally last cells if ( ci(1) .eq. ucob(1) .and. i .eq. sub(1) ) then count(4) = 2_iarr * abs( s(i,j,k) - s(i+1,j,k) ) - 1_iarr end if if ( ci(2) .eq. ucob(2) .and. j .eq. sub(2) ) then count(5) = 2_iarr * abs( s(i,j,k) - s(i,j+1,k) ) - 1_iarr end if if ( ci(3) .eq. ucob(3) .and. k .eq. sub(3) ) then count(6) = 2_iarr * abs( s(i,j,k) - s(i,j,k+1) ) - 1_iarr end if ca_kernel_ising_ener = sum( count ) ! write (*,"(a,4(i0,tr1))") "i,j,k,energy:", i,j,k,ca_kernel_ising_ener end associate end function ca_kernel_ising_ener
ca_hx/ca_run [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_run
SYNOPSIS
subroutine ca_run( space, hx_sub, iter_sub, kernel, niter )
INPUT
integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) procedure( hx_proto ) :: hx_sub procedure( iter_proto ) :: iter_sub procedure( kernel_proto ) :: kernel integer, intent(in) :: niter ! space - space array before iterations start ! hx_sub - HX routine, e.g. ! - ca_hx_all ! _ ca_mpi_hx_all ! iter_sub - the subroutine performing a single CA iteration, e.g. ! - ca_iter_tl - triple nested loop ! - ca_iter_dc - do concurrent ! - ca_iter_omp - OpenMP ! kernel - a function to be called for every cell inside the loop ! iter - number of iterations to do
OUTPUT
! space - CA array at the end of niter iterations
SIDE EFFECTS
module array tmp_space is updated
DESCRIPTION
This is a driver routine for CA iterations. HX is done before each iteration. Then a given number of iterations is performed with a given routine and a given kernel. One iteration is really 2 iterations: odd and even, Hence the upper loop limit is 2*niter.
USES
USED BY
SOURCE
integer :: i tmp_space = space do i = 1, 2*niter call hx_sub( space ) ! space updated, with HX ! tmp_space updated, local op call iter_sub( space=space, halo=hdepth, kernel=kernel ) space = tmp_space ! local op mask_array = 1_iarr - mask_array ! Flip the mask array end do end subroutine ca_run
ca_hx/ca_set_space_rnd [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_set_space_rnd
SYNOPSIS
subroutine ca_set_space_rnd( seed, frac1, space )
INPUT
integer :: seed(:) real :: frac1 ! seed - RND seed array ! frac1 - fraction of "1" cells, spin up cells, [0..1].
OUTPUT
integer( kind=iarr ), intent( inout ), contiguous :: & space( 1-hdepth: , 1-hdepth:, 1-hdepth: ) ! space - CA array is set to reproducible RND values, and ! in a way that the global CA array is not dependent ! on the partition or the number of images
SIDE EFFECTS
A tmp external file is created from image 1 to store RND values. It is deleted at the exit from this routine, also by image 1.
DESCRIPTION
Must call this routine after ca_halloc. Generate a 1D array or RND from a given seed. The length of the array is the size of the global CA model, i.e. don't generate values for the halos. Image 1 writes this array to file. Then, inside a critical region each image reads its own data. This is a slow routine.
SOURCE
integer :: co_k, co_j, co_i, k, j, i, funit integer( kind=iarr ) :: value integer( kind=iarr ), allocatable :: rnd_arr_int(:) real, allocatable :: rnd_arr(:) character(:), allocatable :: fname fname = "tmp_rnd_file" ! Image 1 sets the file make_file: if ( this_image() .eq. 1 ) then ! Sanity check if ( frac1 .lt. 0.0 .or. frac1 .gt. 1.0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: frac1 outside of" // & " admissable range [0..1]: frac1:", frac1 error stop end if write (*,*) ! total_cells would have been set already in ca_spalloc ! No halo cells are included in this number! allocate( rnd_arr( total_cells ) ) allocate( rnd_arr_int( total_cells ) ) call random_seed( put = seed ) call random_number( rnd_arr ) ! rnd_arr_int = nint( rnd_arr ) rnd_arr_int = 0 where ( rnd_arr .lt. frac1 ) rnd_arr_int = 1 end where open( newunit=funit, file=fname, status="replace", access="stream", & form="unformatted", iostat=ierr ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: " // & "open( fname ), ierr:", ierr error stop end if write (funit) rnd_arr_int close(funit, status="keep", iostat=ierr ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: " // & "close( fname ), ierr:", ierr error stop end if deallocate( rnd_arr ) deallocate( rnd_arr_int ) end if make_file ! All images wait for img1 to write data to file and close it. sync all ! Each image in turn reads the data from the file critical open( newunit=funit, file=fname, status="old", access="stream", & form="unformatted", iostat=ierr ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: " // & "open( fname ), ierr:", ierr end if do co_k = 1, ucob(3) do k = 1, sub(3) do co_j = 1, ucob(2) do j = 1, sub(2) do co_i = 1, ucob(1) do i = 1, sub(1) read( funit ) value if ( co_k .eq. ci(3) .and. co_j .eq. ci(2) .and. & co_i .eq. ci(1) ) then ! ===>>> NOTE <<<=== ! Only real space cells are assigned value! ! The halo cells are set to 0 in ca_spalloc! space(i,j,k) = value end if end do end do end do end do end do end do close(funit, status="keep", iostat=ierr ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: " // & "close( fname ), ierr:", ierr end if end critical ! All images must read their data before image 1 deletes the file sync all ! Image 1 deletes the file file_delete: if ( this_image() .eq. 1 ) then open( newunit=funit, file=fname, status="old", iostat=ierr ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: " // & "open( fname ), ierr:", ierr error stop end if close(funit, status="delete", iostat=ierr ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_set_space_rnd: " // & "close( fname ), ierr:", ierr error stop end if end if file_delete end subroutine ca_set_space_rnd
ca_hx/ca_spalloc [ Subroutines ]
[ Top ] [ ca_hx ] [ Subroutines ]
NAME
ca_spalloc
SYNOPSIS
subroutine ca_spalloc( space, c, do )
INPUT
integer( kind=iarr ), allocatable, intent(inout) :: space(:,:,:) integer, intent(in) :: c(3), do ! space - CA array to allocate, with halos! ! c - array with space dimensions ! d - depth of the halo layer
OUTPUT
! space is allocated and set to zero.
SIDE EFFECTS
none
DESCRIPTION
This routine allocates the CA array space, with halos of depth d. Also save some vars in this module for future. Also, on first call, allocate a module work space array (tmp_space) of the same mold as space. This array is used in CA iterations later.
USES
USED BY
SOURCE
if ( allocated( space ) ) then write (*,*) "WARN: ca_hx/ca_spalloc: image:", this_image(), "space", & "already allocated, deallocating!" deallocate( space, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_spalloc: deallocate( space ), ierr:", & ierr, "errmsg:", trim(errmsg) error stop end if end if ! Note that halo cells are set to 0 here too. allocate( space( 1-do:c(1)+do, 1-do:c(2)+do, 1-do:c(3)+do ), source=0_iarr, & stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,*) "ERROR: ca_hx/ca_spalloc: allocate( space ), ierr:", & ierr, "errmsg:", trim(errmsg) error stop end if ! Calculate once and keep forever ! Need a picture to explain these halo vars. ! The picture is only for dimension 1. ! The same diagram can be drawn for dimensions 2 and 3. ! ! hdepth ! | | ! +----+---------------------+----+-- ! | | | | ^ hdepth ! | | | | v ! +----+---------------------+----+-- ! |<-lhsta | | | | ! | 0| | | | | ! | |1 | | | | ! | hdepth->| | | | ! | | | |<-ihsta | ! | | | sub->| | ! | | | | |<-rhsta ! | | | | rhend->| ! | | | | | | ! +----+---------------------+----+ ! | | | | ! | | | | ! +----+---------------------+----+ hdepth = do sub = c ihsta = sub - hdepth + 1 rhsta = sub + 1 rhend = sub + hdepth lhsta = -hdepth + 1 if ( this_image() .eq. 1 ) write (*,*) "spalloc: hdepth:", hdepth, & "sub:", sub, "ihsta:", ihsta, "rhsta:", rhsta, "rhend:", rhend, & "lhsta:", lhsta ! Total number of cells in the global CA total_cells = sub(1)*sub(2)*sub(3)*num_images() ! tmp_space must be (re)allocated. if ( allocated( tmp_space ) ) then deallocate( tmp_space, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,"(a,i0,a,a)") "ERROR: ca_hx/ca_spalloc: " // & "deallocate( tmp_space ), ierr: ", ierr, "errmsg:", trim(errmsg) error stop end if end if ! Note that halo cells are set to 0 here too. allocate( tmp_space, source=space, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,"(a,i0,a,a)") "ERROR: ca_hx/ca_spalloc: " // & "allocate( tmp_space ), ierr: ", ierr, " errmsg: ", trim(errmsg) error stop end if ! mask_array must be (re)allocated. ! Mask array, no halos, the values are set in ca_halloc. if ( allocated( mask_array ) ) then deallocate( mask_array, stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,"(a,i0,a,a)") "ERROR: ca_hx/ca_spalloc: " // & "deallocate( mask_array ), ierr: ", ierr, "errmsg:", trim(errmsg) error stop end if end if allocate( mask_array( c(1), c(2), c(3) ), stat=ierr, errmsg=errmsg ) if ( ierr .ne. 0 ) then write (*,"(a,i0,a,a)") "ERROR: ca_hx/ca_spalloc: " // & "allocate( mask_array ) ", "ierr:", ierr, "errmsg:", trim(errmsg) error stop end if end subroutine ca_spalloc
CASUP/ca_hx [ Modules ]
NAME
ca_hx
SYNOPSIS
!$Id: ca_hx.f90 557 2018-10-10 16:29:20Z mexas $ module ca_hx
DESCRIPTION
Module with halo exchange for casup, the 2nd gen CA library for SUPercomputers. In this module halos are separate arrays from the central part of CA, which is not a coarray.
AUTHOR
Anton Shterenlikht
COPYRIGHT
See LICENSE
CONTAINS
Public subroutines: ca_spalloc, ca_halloc, ca_hdalloc, ca_hx_all, ca_hx_glbar, ca_hx_check, ca_iter_dc, ca_iter_omp, ca_iter_tl, ca_run, ca_ising_energy, ca_ising_energy_col, ca_set_space_rnd, ca_mpi_halo_type_create, ca_mpi_halo_type_free, ca_mpi_hx_all, ca_mpi_ising_energy, ca_co_spalloc, ca_co_hx_all, ca_co_hx_check, ca_co_run, ca_co_ising_energy, ca_co_netcdf, ca_co_naive_io, ca_1D_halloc, ca_1D_hdalloc, ca_1D_hx_sall, ca_1D_hx_check. Public pure functions: ca_kernel_copy, ca_kernel_ising, ca_kernel_ising_ener. Private subroutines: in submodule ca_hx_mpi: ca_mpi_hxvn1m, ca_mpi_hxvn1p, ca_mpi_hxvn2m, ca_mpi_hxvn2p, ca_mpi_hxvn3m, ca_mpi_hxvn3p.
USES
USED BY
SOURCE
use cgca_m1co, only : ca_range, iarr, idef, ilrg use mpi implicit none private public :: ca_spalloc, ca_halloc, ca_hdalloc, ca_hx_all, ca_hx_glbar, & ca_hx_check, & ca_iter_dc, ca_iter_omp, ca_iter_tl, ca_run, ca_kernel_copy, & ca_kernel_ising, ca_kernel_ising_ener, & ca_ising_energy, ca_ising_energy_col, & ca_set_space_rnd, & ca_mpi_halo_type_create, ca_mpi_halo_type_free, & ca_mpi_hx_all, ca_mpi_ising_energy, & ca_co_spalloc, ca_co_hx_all, ca_co_hx_check, ca_co_run, & ca_co_ising_energy, ca_co_netcdf, ca_co_naive_io, & ca_1D_halloc, ca_1D_hdalloc, ca_1D_hx_sall, ca_1D_hx_check ! These are halo coarrays. Parts of the CA array are designated ! "halo", but those are not coarrays. ! ! h1 - halo along dimension 1. ! h2 - halo along dimension 1. ! h3 - halo along dimension 1. ! "minu" - minus, "plus" - plus. ! "t" - tmp arrays. integer( kind=iarr ), allocatable :: & h1minu(:,:,:)[:,:,:], h1plus(:,:,:)[:,:,:], & h2minu(:,:,:)[:,:,:], h2plus(:,:,:)[:,:,:], & h3minu(:,:,:)[:,:,:], h3plus(:,:,:)[:,:,:], & tmp_space(:,:,:), mask_array(:,:,:) integer :: hdepth, & ! halo depth ci(3), & ! coindex set of my image ucob(3), & ! upper cobounds of halo coarrays ihsta(3), & ! inner right halo start rhsta(3), & ! outer right halo start rhend(3), & ! outer right halo end lhsta(3), & ! outer left halo start sub(3), & ! upper bounds of space array (without halo) ierr, & ! error variable total_cells, & ! total number of cells in the global CA. nei_ci_L1(3), & ! coindex set of left neighbour along 1 nei_ci_R1(3), & ! coindex set of right neighbour along 1 nei_ci_L2(3), & ! coindex set of left neighbour along 2 nei_ci_R2(3), & ! coindex set of right neighbour along 2 nei_ci_L3(3), & ! coindex set of left neighbour along 3 nei_ci_R3(3), & ! coindex set of right neighbour along 3 nei_img_L(3), & ! image indices for 3 left neighbours nei_img_R(3) ! image indices for 3 right neighbours ! A scalar to calculate the total energy of CA ! These will not be needed when collectives can be used. integer( kind=ilrg ) :: co_energy[*], co_magnet[*] character( len=500 ) :: errmsg abstract interface !**************************************************************** ! Cray bug in 8.6.5! ! Should be able to use hdepth from the module via IMPORT! ! When fixed, remove "halo" and change back to use "hdepth" ! in this module, ca_hx_co and ca_hx_mpi! !**************************************************************** !*******************************************************************72 ! For non-coarray CA model !*******************************************************************72 ! For a kernel function pure function kernel_proto( space, halo, coord ) use cgca_m1co ! import hdepth implicit none integer, intent(in) :: halo integer( kind=iarr ), intent(in), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) integer, intent(in) :: coord(3) integer( kind=iarr ) kernel_proto end function kernel_proto ! For a subroutine doing a single iteration subroutine iter_proto( space, halo, kernel ) use cgca_m1co import :: kernel_proto implicit none integer, intent( in ) :: halo integer( kind=iarr ), intent(in), contiguous :: & space( 1-halo: , 1-halo: , 1-halo: ) procedure( kernel_proto ) :: kernel end subroutine iter_proto ! For a HX routine subroutine hx_proto( space ) use cgca_m1co implicit none integer( kind=iarr ), intent( inout ), allocatable :: space(:,:,:) end subroutine hx_proto !*******************************************************************72 ! For coarray CA model !*******************************************************************72 ! For a HX routine subroutine hx_co_proto( space ) use cgca_m1co implicit none integer( kind=iarr ), intent( inout ), allocatable :: & space(:,:,:)[:,:,:] end subroutine hx_co_proto !*******************************************************************72 ! For MPI HX !*******************************************************************72 subroutine hx_mpi_proto( space ) use cgca_m1co implicit none integer( kind=iarr ), intent( inout ), allocatable :: space(:,:,:) end subroutine hx_mpi_proto end interface ! Interfaces for submodule procedures. interface !*******************************************************************72 ! In submodule ca_hx_mpi !*******************************************************************72 module subroutine ca_mpi_halo_type_create( space ) integer( kind=iarr ), intent( inout ), allocatable :: space(:,:,:) end subroutine ca_mpi_halo_type_create module subroutine ca_mpi_halo_type_free end subroutine ca_mpi_halo_type_free module subroutine ca_mpi_hxvn1m( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hxvn1m module subroutine ca_mpi_hxvn1p( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hxvn1p module subroutine ca_mpi_hxvn2m( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hxvn2m module subroutine ca_mpi_hxvn2p( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hxvn2p module subroutine ca_mpi_hxvn3m( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hxvn3m module subroutine ca_mpi_hxvn3p( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hxvn3p module subroutine ca_mpi_hx_all( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_mpi_hx_all module subroutine ca_mpi_ising_energy( space, hx_sub, iter_sub, & kernel, energy, magnet ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) procedure( hx_mpi_proto ) :: hx_sub procedure( iter_proto ) :: iter_sub procedure( kernel_proto ) :: kernel integer( kind=ilrg ), intent(out) :: energy, magnet end subroutine ca_mpi_ising_energy !*******************************************************************72 ! In submodule ca_hx_co !*******************************************************************72 module subroutine ca_co_spalloc( space, c, do, ir ) integer( kind=iarr ), intent( inout ), allocatable :: & space(:,:,:) [:,:,:] integer, intent(in) :: c(3), do, ir(3) end subroutine ca_co_spalloc module subroutine ca_co_hx_all( space ) integer( kind=iarr ), intent( inout ), allocatable :: & space(:,:,:) [:,:,:] end subroutine ca_co_hx_all module subroutine ca_co_hx_check( space, flag ) integer( kind=iarr ), intent( in ), allocatable :: & space(:,:,:) [:,:,:] integer, intent( out ) :: flag end subroutine ca_co_hx_check module subroutine ca_co_run( space, hx_sub, iter_sub, kernel, niter ) integer( kind=iarr ), intent( inout ), allocatable :: & space(:,:,:) [:,:,:] procedure( hx_co_proto ) :: hx_sub procedure( iter_proto ) :: iter_sub procedure( kernel_proto ) :: kernel integer, intent(in) :: niter end subroutine ca_co_run module subroutine ca_co_ising_energy( space, hx_sub, iter_sub, & kernel, energy, magnet ) integer( kind=iarr ), intent( inout ), allocatable :: & space(:,:,:)[:,:,:] procedure( hx_co_proto ) :: hx_sub procedure( iter_proto ) :: iter_sub procedure( kernel_proto ) :: kernel integer( kind=ilrg) , intent(out) :: energy, magnet end subroutine ca_co_ising_energy module subroutine ca_co_netcdf( space, fname ) integer( kind=iarr ), intent( in ), allocatable :: & space(:,:,:) [:,:,:] character( len=* ), intent( in ) :: fname end subroutine ca_co_netcdf module subroutine ca_co_naive_io( coarray, fname ) integer( kind=iarr ), intent( in ), allocatable :: & coarray(:,:,:) [:,:,:] character( len=* ),intent( in ) :: fname end subroutine ca_co_naive_io !*******************************************************************72 ! In submodule ca_hx_1D !*******************************************************************72 module subroutine ca_1D_halloc end subroutine ca_1D_halloc module subroutine ca_1D_hdalloc end subroutine ca_1D_hdalloc module subroutine ca_1D_hx_sall( space ) integer( kind=iarr ), intent(inout), allocatable :: space(:,:,:) end subroutine ca_1D_hx_sall module subroutine ca_1D_hx_check( space, flag ) integer( kind=iarr ), intent(in), allocatable :: space(:,:,:) integer, intent( out ) :: flag end subroutine ca_1D_hx_check end interface contains