FV3 Bundle
tapenade_iter.F90
Go to the documentation of this file.
2 
3 ! 20170413 | D.Holdaway | Tool for customised interfacing with Tapenade checkpointing in an iterative environment
4 ! 20171010 | D.Holdaway | Update to use derived types and generalize for access by multiple modules
5 
6 !Functionality this module provides
7 ! - Hold checkpoints in memory accross multiple iterations.
8 ! - Compile time precision choice for real variables.
9 ! - Profile a subroutine to see how much memory it uses.
10 
11 #ifdef SPMD
12  use mpi
13 #endif
14 
15  implicit none
16  private
17 
18 !Derived type for holding all the controls for the iterative use of checkpoitning
19 !--------------------------------------------------------------------------------
21  integer :: cp_nt !Number of time steps
22  integer :: cp_i !Iteration number
23  integer :: cp_t !Current time step
24  real :: cp_gb !User estimated number of gigabytes avaialable per processor
25  integer :: cp_nm !Number of modules using this routine
26  end type
27 
28  !Global for all modules using custom checkpointing
30 
31  !Index in arrays for different types of checkpointed variables
32  integer, parameter :: idx_control = 1
33  integer, parameter :: idx_integer = 2
34  integer, parameter :: idx_real_r4 = 3
35  integer, parameter :: idx_real_r8 = 4
36  integer, parameter :: total_types = 4 !Total variable types
37 
38  integer, parameter :: status_kind = 1
39 
40 !Derived type for holding all the checkpoints and
41 !information about checkpoints for a given module
42 !------------------------------------------------
44 
45  !User provided
46  character(len=3) :: my_name !User defined name for this module
47  logical :: cp_test !Testing mode
48  logical :: cp_rep !Write reports on checkpointing
49  logical :: cp_nscp !Checkpoint all n-splits?
50  logical :: cp_adm_pp !Make sure _adm calls do not use custom checkpointing
51  logical :: check_st_control !Check whether control push/pops are necessary
52  logical :: check_st_integer !Check whether control push/pops are necessary
53  logical :: check_st_real_r4 !Check whether control push/pops are necessary
54  logical :: check_st_real_r8 !Check whether control push/pops are necessary
55  integer :: test_dim_st_control !Dimension of arrays in test mode
56  integer :: test_dim_st_integer
57  integer :: test_dim_st_real_r4
58  integer :: test_dim_st_real_r8
59  integer :: test_dim_cp_control
60  integer :: test_dim_cp_integer
61  integer :: test_dim_cp_real_r4
62  integer :: test_dim_cp_real_r8
63 
64  !Counts for both number of checkpoints and dimension of all checkpoints
65  integer, allocatable :: count_psh(:,:)
66  integer, allocatable :: count_pop(:,:)
67  integer, allocatable :: index_psh(:,:)
68  integer, allocatable :: index_pop(:,:)
69 
70  !Arrays for holding status of checkpoints
71  integer(kind=status_kind), allocatable :: st_control(:,:)
72  integer(kind=status_kind), allocatable :: st_integer(:,:)
73  integer(kind=status_kind), allocatable :: st_real_r4(:,:)
74  integer(kind=status_kind), allocatable :: st_real_r8(:,:)
75 
76  !Arrays for holding checkpoints
77  integer, allocatable :: cp_control(:,:)
78  integer, allocatable :: cp_integer(:,:)
79  real(4), allocatable :: cp_real_r4(:,:)
80  real(8), allocatable :: cp_real_r8(:,:)
81 
82  !Ability to turn recording on and off for stages of loops
83  logical :: recording = .true.
84  logical :: loop_last_step = .false.
85 
86  integer, allocatable :: count_pop_start(:,:)
87  integer, allocatable :: index_pop_start(:,:)
88 
89  end type cp_iter_type
90 
91  !All the checkpoints are contained here
92  logical, save :: cp_iter_initialized = .false.
93  logical, save :: cp_iter_finalized = .false.
94  type(cp_iter_type), allocatable, target :: cp_iter(:)
95 
96  !Pointer to active module checkpointing
97  type(cp_iter_type), pointer :: am
98 
99  !Bytes to mb and gb, RAM so 1024^x convention
100  real(8), parameter :: b2mb = 9.536743164062500d-7 !1024.0**-2
101  real(8), parameter :: b2gb = 9.313225746154785d-10 !1024.0**-3
102 
103  !Counter checking that no push attempts in backwards phase
104  integer(8) :: count_psh_mid(total_types)
105 
106  !Convenience pointers
107  integer, pointer :: cp_nt, cp_i, cp_t, cp_nm
108  real, pointer :: cp_gb
109 
110 #ifdef SPMD
111  integer :: mpierr
112 #endif
113  logical, save :: root_pe = .false.
114 
115 !Publicize routines and variables
116 !--------------------------------
117 
118  !Checkpointing controls
119  public cp_iter_controls, cp_iter
120 
121  !Subroutines for controls and testing
123 
124  !Checkpoint interfaces for fwd/bwd
125  public pushcontrol, popcontrol, &
128 
129  !Checkpoint interfaces for adm
131 
132 !Interfaces for the fwd/bwd/adm checkpointing subroutines
133 !--------------------------------------------------------
134 
135  !Checkpointing used in the fwd/bwd routines
136  interface pushinteger
137  module procedure psh_integer_k0
138  module procedure psh_integer_k1
139  end interface
140 
141  interface popinteger
142  module procedure pop_integer_k0
143  module procedure pop_integer_k1
144  end interface
145 
146  interface pushrealarray
147  module procedure psh_real_r4_k0
148  module procedure psh_real_r4_k1
149  module procedure psh_real_r4_k2
150  module procedure psh_real_r4_k3
151  module procedure psh_real_r4_k4
152  module procedure psh_real_r8_k0
153  module procedure psh_real_r8_k1
154  module procedure psh_real_r8_k2
155  module procedure psh_real_r8_k3
156  module procedure psh_real_r8_k4
157  end interface
158 
159  interface poprealarray
160  module procedure pop_real_r4_k0
161  module procedure pop_real_r4_k1
162  module procedure pop_real_r4_k2
163  module procedure pop_real_r4_k3
164  module procedure pop_real_r4_k4
165  module procedure pop_real_r8_k0
166  module procedure pop_real_r8_k1
167  module procedure pop_real_r8_k2
168  module procedure pop_real_r8_k3
169  module procedure pop_real_r8_k4
170  end interface
171 
172  !Checkpointing used in the adm routines, included only to provide compile time precision choice
174  module procedure psh_adm_real_r4_k0
175  module procedure psh_adm_real_r4_k1
176  module procedure psh_adm_real_r4_k2
177  module procedure psh_adm_real_r4_k3
178  module procedure psh_adm_real_r4_k4
179  module procedure psh_adm_real_r8_k0
180  module procedure psh_adm_real_r8_k1
181  module procedure psh_adm_real_r8_k2
182  module procedure psh_adm_real_r8_k3
183  module procedure psh_adm_real_r8_k4
184  end interface
185 
187  module procedure pop_adm_real_r4_k0
188  module procedure pop_adm_real_r4_k1
189  module procedure pop_adm_real_r4_k2
190  module procedure pop_adm_real_r4_k3
191  module procedure pop_adm_real_r4_k4
192  module procedure pop_adm_real_r8_k0
193  module procedure pop_adm_real_r8_k1
194  module procedure pop_adm_real_r8_k2
195  module procedure pop_adm_real_r8_k3
196  module procedure pop_adm_real_r8_k4
197  end interface
198 
199 contains
200 
201 
202 ! Global initialize, called once
203 ! ------------------------------
204 
205  subroutine initialize_cp_iter
207 #ifdef SPMD
208  logical :: is_mpi_init
209  logical :: mpi_init_here
210  integer :: pe_id
211 #endif
212 
213  if (.not. cp_iter_initialized) then
214 
215  !Set convenience pointers
216  cp_nt => cp_iter_controls%cp_nt
217  cp_i => cp_iter_controls%cp_i
218  cp_t => cp_iter_controls%cp_t
219  cp_nm => cp_iter_controls%cp_nm
220  cp_gb => cp_iter_controls%cp_gb
221 
222  if (cp_i == 0) return !Not using the tool
223 
224  allocate(cp_iter(cp_nm))
225 
226  !Intiailize MPI
227 #ifdef SPMD
228  !Check if initialized
229  call mpi_initialized(is_mpi_init,mpierr)
230 
231  !If MPI not itnialized then do that here
232  mpi_init_here = .false.
233  if (.not. is_mpi_init) then
234  call mpi_init(mpierr)
235  is_mpi_init = .true.
236  mpi_init_here = .true.
237  endif
238 
239  call mpi_comm_rank(mpi_comm_world, pe_id, mpierr)
240  if (pe_id == 0) then
241  root_pe = .true.
242  endif
243  if (root_pe .and. mpi_init_here) write(*,*) 'MPI initialized by iterative checkpointing tool'
244  if (root_pe .and. .not.mpi_init_here) write(*,*) 'MPI already initialized'
245 #else
246  root_pe = .true.
247 #endif
248 
249  cp_iter_initialized = .true.
250 
251  endif
252 
253  end subroutine initialize_cp_iter
254 
255  subroutine finalize_cp_iter
257  if (.not. cp_iter_finalized) then
258 
259  nullify(cp_nt)
260  nullify(cp_i )
261  nullify(cp_t )
262  nullify(cp_nm)
263  nullify(cp_gb)
264 
265  if (allocated(cp_iter)) deallocate(cp_iter)
266 
267  cp_iter_finalized = .true.
268 
269  endif
270 
271  end subroutine finalize_cp_iter
272 
273 
274 ! Initialize called by each module accessing this tool
275 ! ----------------------------------------------------
276 
277  subroutine cp_mod_ini(cp_mod_index)
279  implicit none
280  integer, intent(in) :: cp_mod_index
281 
282  !Call intialize, usually already done
283  !------------------------------------
285 
286 
287  !Set pointer to the tool wide active calling module
288  !--------------------------------------------------
289  am => cp_iter(cp_mod_index)
290 
291 
292  !Write information at user request
293  !---------------------------------
294  if (cp_i .ne. 0 .and. am%cp_rep) then
295  if ( root_pe ) then
296  write(*,"(A)") ' '
297  write(*,"(A)") 'Checkpointing information...'
298  write(*,"(A,I4,A,I4)") 'Iteration number : ', cp_i
299  write(*,"(A,I4,A,I4)") 'Time step in iter: ', cp_t, ' of, ', cp_nt
300  write(*,"(A)") ' '
301  write(*,"(A)") 'Active module information:'
302  write(*,"(A)") 'Name: '//am%my_name
303  write(*,"(A,L)") 'Running test mode for module: ', am%cp_test
304  write(*,"(A)") ' '
305  endif
306  endif
307 
308 
309  !Iteration specific initializations
310  !----------------------------------
311  if (cp_t == 1) then
312 
313  if (cp_i == 1) then
314 
315  !Allocate space for push counters
316  allocate(am%count_psh(cp_nt,total_types)); am%count_psh = 0
317  allocate(am%count_pop(cp_nt,total_types)); am%count_pop = 0
318  allocate(am%index_psh(cp_nt,total_types)); am%index_psh = 0
319  allocate(am%index_pop(cp_nt,total_types)); am%index_pop = 0
320 
321  elseif (cp_i == 2) then
322 
323  if (am%cp_test) then
324  !Not allocated as running only this iteration
325  allocate(am%count_psh(cp_nt,total_types)); am%count_psh = 0
326  allocate(am%count_pop(cp_nt,total_types)); am%count_pop = 0
327  allocate(am%index_psh(cp_nt,total_types)); am%index_psh = 0
328  allocate(am%index_pop(cp_nt,total_types)); am%index_pop = 0
329  !Maximum over all time steps and processors, from previous iter and user provided
330  am%count_psh(:,idx_control) = am%test_dim_st_control
331  am%count_psh(:,idx_integer) = am%test_dim_st_integer
332  am%count_psh(:,idx_real_r4) = am%test_dim_st_real_r4
333  am%count_psh(:,idx_real_r8) = am%test_dim_st_real_r8
334  endif
335 
336  !Allocate space for checkpoint status
337  if (am%check_st_control) allocate(am%st_control(cp_nt,maxval(am%count_psh(:,idx_control)))); am%st_control = 1
338  if (am%check_st_integer) allocate(am%st_integer(cp_nt,maxval(am%count_psh(:,idx_integer)))); am%st_integer = 1
339  if (am%check_st_real_r4) allocate(am%st_real_r4(cp_nt,maxval(am%count_psh(:,idx_real_r4)))); am%st_real_r4 = 1
340  if (am%check_st_real_r8) allocate(am%st_real_r8(cp_nt,maxval(am%count_psh(:,idx_real_r8)))); am%st_real_r8 = 1
341 
342  !Once allocated reset counters
343  am%count_psh = 0
344  am%index_psh = 0
345 
346  elseif (cp_i == 3) then
347 
348  if (am%cp_test) then
349  !Not allocated as running only this iteration
350  allocate(am%count_psh(cp_nt,total_types)); am%count_psh = 0
351  allocate(am%count_pop(cp_nt,total_types)); am%count_pop = 0
352  allocate(am%index_psh(cp_nt,total_types)); am%index_psh = 0
353  allocate(am%index_pop(cp_nt,total_types)); am%index_pop = 0
354  !Maximum over all time steps and processors, from previous iter and user provided
355  am%count_psh(:,idx_control) = am%test_dim_st_control
356  am%count_psh(:,idx_integer) = am%test_dim_st_integer
357  am%count_psh(:,idx_real_r4) = am%test_dim_st_real_r4
358  am%count_psh(:,idx_real_r8) = am%test_dim_st_real_r8
359  !Maximum over all time steps and processors, from previous iter and user provided
360  am%index_psh(:,idx_control) = am%test_dim_cp_control
361  am%index_psh(:,idx_integer) = am%test_dim_cp_integer
362  am%index_psh(:,idx_real_r4) = am%test_dim_cp_real_r4
363  am%index_psh(:,idx_real_r8) = am%test_dim_cp_real_r8
364  endif
365 
366  allocate(am%count_pop_start(cp_nt,total_types)); am%count_pop_start = 0
367  allocate(am%index_pop_start(cp_nt,total_types)); am%index_pop_start = 0
368 
369  !Allocate space for checkpoints
370  allocate(am%cp_control(cp_nt,maxval(am%index_pop(:,idx_control)))); am%cp_control = 0
371  allocate(am%cp_integer(cp_nt,maxval(am%index_pop(:,idx_integer)))); am%cp_integer = 0
372  allocate(am%cp_real_r4(cp_nt,maxval(am%index_pop(:,idx_real_r4)))); am%cp_real_r4 = 0.0_4
373  allocate(am%cp_real_r8(cp_nt,maxval(am%index_pop(:,idx_real_r8)))); am%cp_real_r8 = 0.0_8
374 
375  !Once allocated reset counters
376  am%count_psh = 0
377  am%index_psh = 0
378 
379  endif
380 
381  endif
382 
383  end subroutine cp_mod_ini
384 
385 
386 ! Mid point after fwd and before bwd parts of the adjoint
387 ! -------------------------------------------------------
388 
389  subroutine cp_mod_mid
391  implicit none
392 
393 #ifdef SPMD
394  integer(8) :: count_tmp(total_types)
395  integer :: types
396 #endif
397 
398 
399  if (cp_i > 1) then
400 
401  !Reset countdowns
402  am%count_pop(cp_t,:) = am%count_psh(cp_t,:)
403  am%index_pop(cp_t,:) = am%index_psh(cp_t,:)
404 
405  elseif (cp_i == 1) then
406 
407  !Counting up for testing so set to zero
408  am%count_pop(cp_t,:) = 0
409 
410  count_psh_mid(idx_control) = int(am%count_psh(cp_t,idx_control),8)
411  count_psh_mid(idx_integer) = int(am%count_psh(cp_t,idx_integer),8)
412  count_psh_mid(idx_real_r4) = int(am%count_psh(cp_t,idx_real_r4),8)
413  count_psh_mid(idx_real_r8) = int(am%count_psh(cp_t,idx_real_r8),8)
414 
415 #ifdef SPMD
416  do types = 1,total_types
417  call mpi_allreduce(count_psh_mid(types),count_tmp(types),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
418  count_psh_mid(types) = count_tmp(types)
419  enddo
420 #endif
421 
422  endif
423 
424  if (cp_i == 3) then
425 
426  am%count_pop_start(cp_t,:) = am%count_psh(cp_t,:)
427  am%index_pop_start(cp_t,:) = am%index_psh(cp_t,:)
428 
429  endif
430 
431  if (cp_i >= 3) then
432 
433  am%count_pop(cp_t,:) = am%count_pop_start(cp_t,:)
434  am%index_pop(cp_t,:) = am%index_pop_start(cp_t,:)
435 
436  endif
437 
438 
439  end subroutine cp_mod_mid
440 
441 
442 !End of module information output and clean up
443 !---------------------------------------------
444 
445  subroutine cp_mod_end
447  implicit none
448 
449  integer(8) :: count_psh(total_types)
450  integer(8) :: index_psh(total_types)
451  integer(8) :: count_pop(total_types)
452 
453 #ifdef SPMD
454  integer(8) :: count_tmp(total_types)
455  integer(8) :: index_tmp(total_types)
456 #endif
457 
458  real(8) :: memuse_pe_st(total_types+1,2)
459  real(8) :: memuse_pe_cp(total_types+1,2)
460  real(8) :: memuse_mn_st(total_types+1,2)
461  real(8) :: memuse_mn_cp(total_types+1,2)
462  real(8) :: memuse_mx_st(total_types+1,2)
463  real(8) :: memuse_mx_cp(total_types+1,2)
464  real(8) :: memuse_su_st(total_types+1,2)
465  real(8) :: memuse_su_cp(total_types+1,2)
466  real(8) :: memsav_pe(total_types+1)
467  real(8) :: memsav_mn(total_types+1)
468  real(8) :: memsav_mx(total_types+1)
469  real(8) :: memsav_su(total_types+1)
470  integer :: types
471 
472  character(len=19) :: int2char
473 
474  if (cp_i == 1) then
475 
476  !Sometimes Tapenade will make use of push to stack during the backward
477  !sweep of the code. This would not be compatible with this utility
478  !since the indexing of the arrays that hold the checkpoints would be
479  !off. It could be gotten around by creating another stack to hold these
480  !checkpoints in, with intenal adjusting of the pointer to the current stack.
481  !However it is often easiest to just modify the Tapenade code. If the below
482  !checks fail the utility will revert to recompting the forward sweep and
483  !will not make any attempt to write the reference state to static memory.
484 
485  count_psh(idx_control) = int(am%count_psh(cp_t,idx_control),8)
486  count_psh(idx_integer) = int(am%count_psh(cp_t,idx_integer),8)
487  count_psh(idx_real_r4) = int(am%count_psh(cp_t,idx_real_r4),8)
488  count_psh(idx_real_r8) = int(am%count_psh(cp_t,idx_real_r8),8)
489 
490 #ifdef SPMD
491  do types = 1,total_types
492  call mpi_allreduce(count_psh(types),count_tmp(types),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
493  count_psh(types) = count_tmp(types)
494  enddo
495 #endif
496 
497  if (maxval(count_psh - count_psh_mid) .ne. 0) then
498 
499  if (root_pe) then
500  write(*,"(A)" ) ' '
501  write(*,"(A)" ) ' !!!!!!!!!!!! WARNING !!!!!!!!!!!'
502  write(*,"(A)" ) ' '
503  write(*,"(A)" ) ' Attempts to push during backward'
504  write(*,"(A)" ) ' sweep detected, this utility '
505  write(*,"(A)" ) ' will not work so reverting to '
506  write(*,"(A)" ) ' doing recomputation. '
507  write(*,"(A)" ) ' '
508  write(*,"(A,I8)") ' control: ', count_psh(idx_control)-count_psh_mid(idx_control)
509  write(*,"(A,I8)") ' integer: ', count_psh(idx_integer)-count_psh_mid(idx_integer)
510  write(*,"(A,I8)") ' real_r4: ', count_psh(idx_real_r4)-count_psh_mid(idx_real_r4)
511  write(*,"(A,I8)") ' real_r8: ', count_psh(idx_real_r8)-count_psh_mid(idx_real_r8)
512  write(*,"(A)" ) ' '
513  write(*,"(A)" ) ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
514  endif
515 
516  cp_i = 0
517  deallocate(am%count_psh)
518  deallocate(am%count_pop)
519  deallocate(am%index_psh)
520  deallocate(am%index_pop)
521 
522  endif
523 
524  endif
525 
526 
527  if (cp_i == 1 .and. am%cp_rep) then
528 
529  count_psh(idx_control) = int(am%count_psh(cp_t,idx_control),8)
530  count_psh(idx_integer) = int(am%count_psh(cp_t,idx_integer),8)
531  count_psh(idx_real_r4) = int(am%count_psh(cp_t,idx_real_r4),8)
532  count_psh(idx_real_r8) = int(am%count_psh(cp_t,idx_real_r8),8)
533 
534  count_pop(idx_control) = int(am%count_pop(cp_t,idx_control),8)
535  count_pop(idx_integer) = int(am%count_pop(cp_t,idx_integer),8)
536  count_pop(idx_real_r4) = int(am%count_pop(cp_t,idx_real_r4),8)
537  count_pop(idx_real_r8) = int(am%count_pop(cp_t,idx_real_r8),8)
538 
539 #ifdef SPMD
540  call mpi_allreduce(count_psh(idx_control),count_tmp(idx_control),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
541  call mpi_allreduce(count_psh(idx_integer),count_tmp(idx_integer),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
542  call mpi_allreduce(count_psh(idx_real_r4),count_tmp(idx_real_r4),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
543  call mpi_allreduce(count_psh(idx_real_r8),count_tmp(idx_real_r8),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
544  count_psh(idx_control) = count_tmp(idx_control)
545  count_psh(idx_integer) = count_tmp(idx_integer)
546  count_psh(idx_real_r4) = count_tmp(idx_real_r4)
547  count_psh(idx_real_r8) = count_tmp(idx_real_r8)
548  call mpi_allreduce(count_pop(idx_control),count_tmp(idx_control),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
549  call mpi_allreduce(count_pop(idx_integer),count_tmp(idx_integer),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
550  call mpi_allreduce(count_pop(idx_real_r4),count_tmp(idx_real_r4),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
551  call mpi_allreduce(count_pop(idx_real_r8),count_tmp(idx_real_r8),1,mpi_long_long,mpi_sum,mpi_comm_world,mpierr)
552  count_pop(idx_control) = count_tmp(idx_control)
553  count_pop(idx_integer) = count_tmp(idx_integer)
554  count_pop(idx_real_r4) = count_tmp(idx_real_r4)
555  count_pop(idx_real_r8) = count_tmp(idx_real_r8)
556 #endif
557 
558  if (root_pe) then
559  write(*,"(A)" ) ' '
560  write(*,"(A)" ) 'COUNTS FORWARD VERSUS COUNTS BACKWARD, SHOULD BE EQUAL '
561  write(*,"(A)" ) ' '
562  write(*,"(A)" ) 'Forward:'
563  write(*,"(A,I8)") 'control = ', count_psh(idx_control)
564  write(*,"(A,I8)") 'integer = ', count_psh(idx_integer)
565  write(*,"(A,I8)") 'real_r4 = ', count_psh(idx_real_r4)
566  write(*,"(A,I8)") 'real_r8 = ', count_psh(idx_real_r8)
567  write(*,"(A)" ) ' '
568  write(*,"(A)" ) 'Backward:'
569  write(*,"(A,I8)") 'control = ', count_pop(idx_control)
570  write(*,"(A,I8)") 'integer = ', count_pop(idx_integer)
571  write(*,"(A,I8)") 'real_r4 = ', count_pop(idx_real_r4)
572  write(*,"(A,I8)") 'real_r8 = ', count_pop(idx_real_r8)
573  write(*,"(A)" ) ' '
574  endif
575 
576  endif
577 
578  if (cp_i == 1 .and. cp_t == cp_nt .and. (am%cp_test .or. am%cp_rep)) then
579 
580  count_psh(idx_control) = int(maxval(am%count_psh(:,idx_control)),8)
581  count_psh(idx_integer) = int(maxval(am%count_psh(:,idx_integer)),8)
582  count_psh(idx_real_r4) = int(maxval(am%count_psh(:,idx_real_r4)),8)
583  count_psh(idx_real_r8) = int(maxval(am%count_psh(:,idx_real_r8)),8)
584 
585 #ifdef SPMD
586  call mpi_allreduce(count_psh(idx_control),count_tmp(idx_control),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
587  call mpi_allreduce(count_psh(idx_integer),count_tmp(idx_integer),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
588  call mpi_allreduce(count_psh(idx_real_r4),count_tmp(idx_real_r4),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
589  call mpi_allreduce(count_psh(idx_real_r8),count_tmp(idx_real_r8),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
590  count_psh(idx_control) = count_tmp(idx_control)
591  count_psh(idx_integer) = count_tmp(idx_integer)
592  count_psh(idx_real_r4) = count_tmp(idx_real_r4)
593  count_psh(idx_real_r8) = count_tmp(idx_real_r8)
594 #endif
595 
596  if (root_pe) then
597  write(*,"(A)" ) ' '
598  write(*,"(A)" ) 'Array dimensions for next iteration'
599  write(*,"(A)" ) 'Module ID: '//am%my_name
600  write(int2char,"(I19)") count_psh(idx_control)
601  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_st_control: ', adjustl(trim(int2char))
602  write(int2char,"(I19)") count_psh(idx_integer)
603  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_st_integer: ', adjustl(trim(int2char))
604  write(int2char,"(I19)") count_psh(idx_real_r4)
605  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_st_real_r4: ', adjustl(trim(int2char))
606  write(int2char,"(I19)") count_psh(idx_real_r8)
607  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_st_real_r8: ', adjustl(trim(int2char))
608  write(*,"(A)" ) ' '
609  endif
610 
611  elseif (cp_i == 2 .and. cp_t == cp_nt .and. (am%cp_test .or. am%cp_rep)) then
612 
613  index_psh(idx_control) = int(maxval(am%index_psh(:,idx_control)),8)
614  index_psh(idx_integer) = int(maxval(am%index_psh(:,idx_integer)),8)
615  index_psh(idx_real_r4) = int(maxval(am%index_psh(:,idx_real_r4)),8)
616  index_psh(idx_real_r8) = int(maxval(am%index_psh(:,idx_real_r8)),8)
617 
618 #ifdef SPMD
619  call mpi_allreduce(index_psh(idx_control),index_tmp(idx_control),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
620  call mpi_allreduce(index_psh(idx_integer),index_tmp(idx_integer),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
621  call mpi_allreduce(index_psh(idx_real_r4),index_tmp(idx_real_r4),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
622  call mpi_allreduce(index_psh(idx_real_r8),index_tmp(idx_real_r8),1,mpi_long_long,mpi_max,mpi_comm_world,mpierr)
623  index_psh(idx_control) = index_tmp(idx_control)
624  index_psh(idx_integer) = index_tmp(idx_integer)
625  index_psh(idx_real_r4) = index_tmp(idx_real_r4)
626  index_psh(idx_real_r8) = index_tmp(idx_real_r8)
627 #endif
628 
629  !Memory use by each type
630  != Positions*precision*bytestogb
631  memuse_pe_st(idx_control,1) = real(maxval(am%count_psh(:,idx_control)) * status_kind ,8) * b2gb
632  memuse_pe_st(idx_integer,1) = real(maxval(am%count_psh(:,idx_integer)) * status_kind ,8) * b2gb
633  memuse_pe_st(idx_real_r4,1) = real(maxval(am%count_psh(:,idx_real_r4)) * status_kind ,8) * b2gb
634  memuse_pe_st(idx_real_r8,1) = real(maxval(am%count_psh(:,idx_real_r8)) * status_kind ,8) * b2gb
635  memuse_pe_st(total_types+1,1) = sum(memuse_pe_st(1:total_types,1))
636 
637  memuse_pe_st(idx_control,2) = real(maxval(am%count_pop(:,idx_control)) * status_kind ,8) * b2gb
638  memuse_pe_st(idx_integer,2) = real(maxval(am%count_pop(:,idx_integer)) * status_kind ,8) * b2gb
639  memuse_pe_st(idx_real_r4,2) = real(maxval(am%count_pop(:,idx_real_r4)) * status_kind ,8) * b2gb
640  memuse_pe_st(idx_real_r8,2) = real(maxval(am%count_pop(:,idx_real_r8)) * status_kind ,8) * b2gb
641  memuse_pe_st(total_types+1,2) = sum(memuse_pe_st(1:total_types,1))
642 
643  memuse_pe_cp(idx_control,1) = real(maxval(am%index_psh(:,idx_control)) * 4 ,8) * b2gb
644  memuse_pe_cp(idx_integer,1) = real(maxval(am%index_psh(:,idx_integer)) * 4 ,8) * b2gb
645  memuse_pe_cp(idx_real_r4,1) = real(maxval(am%index_psh(:,idx_real_r4)) * 4 ,8) * b2gb
646  memuse_pe_cp(idx_real_r8,1) = real(maxval(am%index_psh(:,idx_real_r8)) * 8 ,8) * b2gb
647  memuse_pe_cp(total_types+1,1) = sum(memuse_pe_cp(1:total_types,1))
648 
649  memuse_pe_cp(idx_control,2) = real(maxval(am%index_pop(:,idx_control)) * 4 ,8) * b2gb
650  memuse_pe_cp(idx_integer,2) = real(maxval(am%index_pop(:,idx_integer)) * 4 ,8) * b2gb
651  memuse_pe_cp(idx_real_r4,2) = real(maxval(am%index_pop(:,idx_real_r4)) * 4 ,8) * b2gb
652  memuse_pe_cp(idx_real_r8,2) = real(maxval(am%index_pop(:,idx_real_r8)) * 8 ,8) * b2gb
653  memuse_pe_cp(total_types+1,2) = sum(memuse_pe_cp(1:total_types,2))
654 
655  !Memory that could be saved by checking the status of a checkpoint
656  memsav_pe(idx_control) = memuse_pe_cp(idx_control,1) - (memuse_pe_cp(idx_control,2) + memuse_pe_st(idx_control,1))
657  memsav_pe(idx_integer) = memuse_pe_cp(idx_integer,1) - (memuse_pe_cp(idx_integer,2) + memuse_pe_st(idx_integer,1))
658  memsav_pe(idx_real_r4) = memuse_pe_cp(idx_real_r4,1) - (memuse_pe_cp(idx_real_r4,2) + memuse_pe_st(idx_real_r4,1))
659  memsav_pe(idx_real_r8) = memuse_pe_cp(idx_real_r8,1) - (memuse_pe_cp(idx_real_r8,2) + memuse_pe_st(idx_real_r8,1))
660  memsav_pe(total_types+1) = sum(memsav_pe(1:total_types))
661 
662  if (.not. am%cp_test) then
663  !Multiply for all time steps
664  memuse_pe_st = memuse_pe_st * real(cp_nt,8)
665  memuse_pe_cp = memuse_pe_cp * real(cp_nt,8)
666  memsav_pe = memsav_pe * real(cp_nt,8)
667  endif
668 
669 #ifdef SPMD
670  !Sum, max and min across processors
671  do types = 1,total_types+1
672  call mpi_allreduce(memuse_pe_st(types,1),memuse_mn_st(types,1),1,mpi_double_precision,mpi_min,mpi_comm_world,mpierr)
673  call mpi_allreduce(memuse_pe_cp(types,1),memuse_mn_cp(types,1),1,mpi_double_precision,mpi_min,mpi_comm_world,mpierr)
674  call mpi_allreduce(memuse_pe_st(types,1),memuse_mx_st(types,1),1,mpi_double_precision,mpi_max,mpi_comm_world,mpierr)
675  call mpi_allreduce(memuse_pe_cp(types,1),memuse_mx_cp(types,1),1,mpi_double_precision,mpi_max,mpi_comm_world,mpierr)
676  call mpi_allreduce(memuse_pe_st(types,1),memuse_su_st(types,1),1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
677  call mpi_allreduce(memuse_pe_cp(types,1),memuse_su_cp(types,1),1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
678  call mpi_allreduce(memuse_pe_st(types,2),memuse_mn_st(types,2),1,mpi_double_precision,mpi_min,mpi_comm_world,mpierr)
679  call mpi_allreduce(memuse_pe_cp(types,2),memuse_mn_cp(types,2),1,mpi_double_precision,mpi_min,mpi_comm_world,mpierr)
680  call mpi_allreduce(memuse_pe_st(types,2),memuse_mx_st(types,2),1,mpi_double_precision,mpi_max,mpi_comm_world,mpierr)
681  call mpi_allreduce(memuse_pe_cp(types,2),memuse_mx_cp(types,2),1,mpi_double_precision,mpi_max,mpi_comm_world,mpierr)
682  call mpi_allreduce(memuse_pe_st(types,2),memuse_su_st(types,2),1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
683  call mpi_allreduce(memuse_pe_cp(types,2),memuse_su_cp(types,2),1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
684  call mpi_allreduce(memsav_pe(types),memsav_mn(types),1,mpi_double_precision,mpi_min,mpi_comm_world,mpierr)
685  call mpi_allreduce(memsav_pe(types),memsav_mx(types),1,mpi_double_precision,mpi_max,mpi_comm_world,mpierr)
686  call mpi_allreduce(memsav_pe(types),memsav_su(types),1,mpi_double_precision,mpi_sum,mpi_comm_world,mpierr)
687  enddo
688 
689  if (root_pe) then
690  write(*,"(A)" ) ' '
691  write(*,"(A)" ) ' MEMORY REQUIREMENTS FOR REFERENCE STATE PUSH (GB of RAM)'
692  write(*,"(A)" ) ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
693  write(*,"(A)" ) ' Minumum across processors (control) '
694  write(*,"(F12.6)" ) memuse_mn_cp(idx_control,1)
695  write(*,"(A)" ) ' Maximum across processors (control) '
696  write(*,"(F12.6)" ) memuse_mx_cp(idx_control,1)
697  write(*,"(A)" ) ' Sum across processors (control) '
698  write(*,"(F12.6)" ) memuse_su_cp(idx_control,1)
699  write(*,"(A)" ) ' '
700  write(*,"(A)" ) ' Minumum across processors (integer) '
701  write(*,"(F12.6)" ) memuse_mn_cp(idx_integer,1)
702  write(*,"(A)" ) ' Maximum across processors (integer) '
703  write(*,"(F12.6)" ) memuse_mx_cp(idx_integer,1)
704  write(*,"(A)" ) ' Sum across processors (integer) '
705  write(*,"(F12.6)" ) memuse_su_cp(idx_integer,1)
706  write(*,"(A)" ) ' '
707  write(*,"(A)" ) ' Minumum across processors (real_r4) '
708  write(*,"(F12.6)" ) memuse_mn_cp(idx_real_r4,1)
709  write(*,"(A)" ) ' Maximum across processors (real_r4) '
710  write(*,"(F12.6)" ) memuse_mx_cp(idx_real_r4,1)
711  write(*,"(A)" ) ' Sum across processors (real_r4) '
712  write(*,"(F12.6)" ) memuse_su_cp(idx_real_r4,1)
713  write(*,"(A)" ) ' '
714  write(*,"(A)" ) ' Minumum across processors (real_r8) '
715  write(*,"(F12.6)" ) memuse_mn_cp(idx_real_r8,1)
716  write(*,"(A)" ) ' Maximum across processors (real_r8) '
717  write(*,"(F12.6)" ) memuse_mx_cp(idx_real_r8,1)
718  write(*,"(A)" ) ' Sum across processors (real_r8) '
719  write(*,"(F12.6)" ) memuse_su_cp(idx_real_r8,1)
720  write(*,"(A)" ) ' '
721  write(*,"(A)" ) ' Minumum across processors (Total) '
722  write(*,"(F12.6)" ) memuse_mn_cp(total_types+1,1)
723  write(*,"(A)" ) ' Maximum across processors (Total) '
724  write(*,"(F12.6)" ) memuse_mx_cp(total_types+1,1)
725  write(*,"(A)" ) ' Sum across processors (Total) '
726  write(*,"(F12.6)" ) memuse_su_cp(total_types+1,1)
727  write(*,"(A)" ) ' '
728  write(*,"(A)" ) ' '
729  write(*,"(A)" ) ' '
730  write(*,"(A)" ) ' '
731  write(*,"(A)" ) ' MEMORY SAVED BY CHECKING THE STATUS OF CHECKPOINTS (GB of RAM)'
732  write(*,"(A)" ) ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
733  write(*,"(A)" ) ' Minumum across processors (control) '
734  write(*,"(F12.6)" ) memsav_mn(idx_control)
735  write(*,"(A)" ) ' Maximum across processors (control) '
736  write(*,"(F12.6)" ) memsav_mx(idx_control)
737  write(*,"(A)" ) ' Sum across processors (control) '
738  write(*,"(F12.6)" ) memsav_su(idx_control)
739  write(*,"(A)" ) ' '
740  write(*,"(A)" ) ' Minumum across processors (integer) '
741  write(*,"(F12.6)" ) memsav_mn(idx_integer)
742  write(*,"(A)" ) ' Maximum across processors (integer) '
743  write(*,"(F12.6)" ) memsav_mx(idx_integer)
744  write(*,"(A)" ) ' Sum across processors (integer) '
745  write(*,"(F12.6)" ) memsav_su(idx_integer)
746  write(*,"(A)" ) ' '
747  write(*,"(A)" ) ' Minumum across processors (real_r4) '
748  write(*,"(F12.6)" ) memsav_mn(idx_real_r4)
749  write(*,"(A)" ) ' Maximum across processors (real_r4) '
750  write(*,"(F12.6)" ) memsav_mx(idx_real_r4)
751  write(*,"(A)" ) ' Sum across processors (real_r4) '
752  write(*,"(F12.6)" ) memsav_su(idx_real_r4)
753  write(*,"(A)" ) ' '
754  write(*,"(A)" ) ' Minumum across processors (real_r8) '
755  write(*,"(F12.6)" ) memsav_mn(idx_real_r8)
756  write(*,"(A)" ) ' Maximum across processors (real_r8) '
757  write(*,"(F12.6)" ) memsav_mx(idx_real_r8)
758  write(*,"(A)" ) ' Sum across processors (real_r8) '
759  write(*,"(F12.6)" ) memsav_su(idx_real_r8)
760  write(*,"(A)" ) ' '
761  write(*,"(A)" ) ' Minumum across processors (total) '
762  write(*,"(F12.6)" ) memsav_mn(total_types+1)
763  write(*,"(A)" ) ' Maximum across processors (total) '
764  write(*,"(F12.6)" ) memsav_mx(total_types+1)
765  write(*,"(A)" ) ' Sum across processors (total) '
766  write(*,"(F12.6)" ) memsav_su(total_types+1)
767  write(*,"(A)" ) ' '
768  endif
769 
770 #else
771 
772  memuse_mn_st = memuse_pe_st
773  memuse_mn_cp = memuse_pe_cp
774  memuse_mx_st = memuse_pe_st
775  memuse_mx_cp = memuse_pe_cp
776  memuse_su_st = memuse_pe_st
777  memuse_su_cp = memuse_pe_cp
778  memsav_mn = memsav_pe
779  memsav_mx = memsav_pe
780  memsav_su = memsav_pe
781 
782  write(*,"(A)" ) ' '
783  write(*,"(A)" ) ' MEMORY REQUIREMENTS FOR REFERENCE STATE (Gb of RAM)'
784  write(*,"(A)" ) ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
785  write(*,"(A)" ) ' Control '
786  write(*,"(F12.6)" ) memuse_su_cp(idx_control,1)
787  write(*,"(A)" ) ' '
788  write(*,"(A)" ) ' Integer '
789  write(*,"(F12.6)" ) memuse_su_cp(idx_integer,1)
790  write(*,"(A)" ) ' '
791  write(*,"(A)" ) ' real_r4 '
792  write(*,"(F12.6)" ) memuse_su_cp(idx_real_r4,1)
793  write(*,"(A)" ) ' '
794  write(*,"(A)" ) ' real_r8 '
795  write(*,"(F12.6)" ) memuse_su_cp(idx_real_r8,1)
796  write(*,"(A)" ) ' '
797  write(*,"(A)" ) ' Total '
798  write(*,"(F12.6)" ) memuse_su_cp(total_types+1,1)
799  write(*,"(A)" ) ' '
800  write(*,"(A)" ) ' '
801  write(*,"(A)" ) ' MEMORY SAVED BY CHECKING THE STATUS OF CHECKPOINTS (Gb of RAM)'
802  write(*,"(A)" ) ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
803  write(*,"(A)" ) ' Control '
804  write(*,"(F12.6)" ) memsav_su(idx_control)
805  write(*,"(A)" ) ' '
806  write(*,"(A)" ) ' Integer '
807  write(*,"(F12.6)" ) memsav_su(idx_integer)
808  write(*,"(A)" ) ' '
809  write(*,"(A)" ) ' real_r4 '
810  write(*,"(F12.6)" ) memsav_su(idx_real_r4)
811  write(*,"(A)" ) ' '
812  write(*,"(A)" ) ' real_r8 '
813  write(*,"(F12.6)" ) memsav_su(idx_real_r8)
814  write(*,"(A)" ) ' '
815 
816 #endif
817 
818  if (root_pe) then
819  write(*,"(A)" ) ' '
820  write(*,"(A)" ) 'Array dimensions for next iteration'
821  write(*,"(A)" ) 'Module ID: '//am%my_name
822  write(int2char,"(I19)") index_psh(idx_control)
823  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_cp_control: ', adjustl(trim(int2char))
824  write(int2char,"(I19)") index_psh(idx_integer)
825  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_cp_integer: ', adjustl(trim(int2char))
826  write(int2char,"(I19)") index_psh(idx_real_r4)
827  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_cp_real_r4: ', adjustl(trim(int2char))
828  write(int2char,"(I19)") index_psh(idx_real_r8)
829  write(*,"(A,A)") 'CP_'//am%my_name//'_dim_cp_real_r8: ', adjustl(trim(int2char))
830  write(*,"(A)" ) ' '
831  endif
832 
833  if (cp_gb > 0) then
834  if (memuse_mx_cp(total_types+1,1) > cp_gb .and. root_pe) then
835 
836  write(*,"(A)" ) ' '
837  write(*,"(A)" ) ' !!!! WARNING !!!!'
838  write(*,"(A)" ) ' '
839  write(*,"(A)" ) ' Maximum expected memory use by this module is '
840  write(*,"(A)" ) ' greater than the user provided estimation for '
841  write(*,"(A)" ) ' the amount available per processor. '
842  write(*,"(A)" ) ' '
843  write(*,"(A)" ) ' Possibility of crash at the next iteration. '
844  write(*,"(A)" ) ' '
845 
846  endif
847  endif
848 
849  endif
850 
851  !Nullify the active module pointer
852  nullify(am)
853 
854  end subroutine cp_mod_end
855 
856 
857 ! pushcontrol
858 ! -----------
859 
860  subroutine pushcontrol(ctype,field)
862  implicit none
863 
864  integer, intent(in) :: ctype,field
865 
866  integer(status_kind) :: docp
867 
868  if (cp_i == 0) then
869 
870  if (ctype == 1) then
871  call pushcontrol1b(field)
872  elseif (ctype == 2) then
873  call pushcontrol2b(field)
874  elseif (ctype == 3) then
875  call pushcontrol3b(field)
876  elseif (ctype == 4) then
877  call pushcontrol4b(field)
878  elseif (ctype == 5) then
879  call pushcontrol5b(field)
880  endif
881 
882  elseif (cp_i == 1 .or. cp_i == 2) then
883 
884  am%count_psh(cp_t,idx_control) = am%count_psh(cp_t,idx_control) + 1
885  am%index_psh(cp_t,idx_control) = am%index_psh(cp_t,idx_control) + 1
886 
887  if (ctype == 1) then
888  call pushcontrol1b(field)
889  elseif (ctype == 2) then
890  call pushcontrol2b(field)
891  elseif (ctype == 3) then
892  call pushcontrol3b(field)
893  elseif (ctype == 4) then
894  call pushcontrol4b(field)
895  elseif (ctype == 5) then
896  call pushcontrol5b(field)
897  endif
898 
899  elseif (cp_i == 3) then
900 
901  am%count_psh(cp_t,idx_control) = am%count_psh(cp_t,idx_control) + 1
902 
903  docp = 1
904  if (am%check_st_control) then
905  docp = am%st_control(cp_t,am%count_psh(cp_t,idx_control))
906  endif
907 
908  if (docp == 1) then
909  am%index_psh(cp_t,idx_control) = am%index_psh(cp_t,idx_control) + 1
910  am%cp_control(cp_t,am%index_psh(cp_t,idx_control)) = field
911  endif
912 
913  endif
914 
915  end subroutine pushcontrol
916 
917 
918 ! popcontrol
919 ! -----------
920 
921  subroutine popcontrol(ctype,field)
923  implicit none
924 
925  integer, intent(in) :: ctype
926  integer, intent(inout) :: field
927  integer :: tmp
928  integer(status_kind) :: docp
929 
930  if (cp_i == 0) then
931 
932  if (ctype == 1) then
933  call popcontrol1b(field)
934  elseif (ctype == 2) then
935  call popcontrol2b(field)
936  elseif (ctype == 3) then
937  call popcontrol3b(field)
938  elseif (ctype == 4) then
939  call popcontrol4b(field)
940  elseif (ctype == 5) then
941  call popcontrol5b(field)
942  endif
943 
944  elseif (cp_i == 1 .or. cp_i == 2) then
945 
946  if (cp_i == 1) am%count_pop(cp_t,idx_control) = am%count_pop(cp_t,idx_control) + 1
947 
948  if (am%check_st_control .and. cp_i == 2) tmp = field
949 
950  if (ctype == 1) then
951  call popcontrol1b(field)
952  elseif (ctype == 2) then
953  call popcontrol2b(field)
954  elseif (ctype == 3) then
955  call popcontrol3b(field)
956  elseif (ctype == 4) then
957  call popcontrol4b(field)
958  elseif (ctype == 5) then
959  call popcontrol5b(field)
960  endif
961 
962  if (am%check_st_control .and. cp_i == 2) then
963  if (field - tmp == 0) then
964  am%st_control(cp_t,am%count_pop(cp_t,idx_control)) = 0
965  am%index_pop(cp_t,idx_control) = am%index_pop(cp_t,idx_control) - 1
966  elseif (field == 0) then
967  am%st_control(cp_t,am%count_pop(cp_t,idx_control)) = -1
968  am%index_pop(cp_t,idx_control) = am%index_pop(cp_t,idx_control) - 1
969  endif
970  am%count_pop(cp_t,idx_control) = am%count_pop(cp_t,idx_control) - 1
971  endif
972 
973  elseif (cp_i >= 3) then
974 
975  docp = 1
976  if (am%check_st_control) then
977  docp = am%st_control(cp_t,am%count_pop(cp_t,idx_control))
978  endif
979  am%count_pop(cp_t,idx_control) = am%count_pop(cp_t,idx_control) - 1
980 
981  if (docp == 1) then
982  field = am%cp_control(cp_t,am%index_pop(cp_t,idx_control))
983  am%index_pop(cp_t,idx_control) = am%index_pop(cp_t,idx_control) - 1
984  elseif (docp == -1) then
985  field = 0
986  endif
987 
988  endif
989 
990  end subroutine popcontrol
991 
992 
993 
994 ! pushinteger
995 ! -----------
996 
997  subroutine psh_integer_k0(field,skip)
999  implicit none
1000 
1001  integer, intent(in) :: field
1002  logical, optional, intent(in) :: skip
1003  logical :: skipcp
1004  integer(status_kind) :: docp
1005 
1006  skipcp = .false.
1007  if (present(skip)) then
1008  skipcp = skip
1009  endif
1010 
1011  if (cp_i == 0) then
1012 
1013  if(.not.skipcp) CALL pushinteger4(field)
1014 
1015  elseif (cp_i == 1 .or. cp_i == 2) then
1016 
1017  if (am%recording) then
1018  am%count_psh(cp_t,idx_integer) = am%count_psh(cp_t,idx_integer) + 1
1019  am%index_psh(cp_t,idx_integer) = am%index_psh(cp_t,idx_integer) + 1
1020  endif
1021 
1022  if(.not.skipcp) CALL pushinteger4(field)
1023 
1024  elseif (cp_i == 3 .and. am%recording) then
1025 
1026  am%count_psh(cp_t,idx_integer) = am%count_psh(cp_t,idx_integer) + 1
1027 
1028  docp = 1
1029  if (am%check_st_integer) then
1030  docp = am%st_integer(cp_t,am%count_psh(cp_t,idx_integer))
1031  endif
1032 
1033  if (docp == 1) then
1034  am%index_psh(cp_t,idx_integer) = am%index_psh(cp_t,idx_integer) + 1
1035  am%cp_integer(cp_t,am%index_psh(cp_t,idx_integer)) = field
1036  endif
1037 
1038  endif
1039 
1040  end subroutine psh_integer_k0
1041 
1042  subroutine psh_integer_k1(field,dimen,skip)
1044  implicit none
1045 
1046  integer, intent(in) :: dimen
1047  integer, intent(in) :: field(dimen)
1048  logical, optional, intent(in) :: skip
1049  logical :: skipcp
1050  integer(status_kind) :: docp
1051 
1052  skipcp = .false.
1053  if (present(skip)) then
1054  skipcp = skip
1055  endif
1056 
1057  if (cp_i == 0) then
1058 
1059  if(.not.skipcp) CALL pushinteger4array(field,dimen)
1060 
1061  elseif (cp_i == 1 .or. cp_i == 2) then
1062 
1063  if (am%recording) then
1064  am%count_psh(cp_t,idx_integer) = am%count_psh(cp_t,idx_integer) + 1
1065  am%index_psh(cp_t,idx_integer) = am%index_psh(cp_t,idx_integer) + dimen
1066  endif
1067 
1068  if(.not.skipcp) CALL pushinteger4array(field,dimen)
1069 
1070  elseif (cp_i == 3 .and. am%recording) then
1071 
1072  am%count_psh(cp_t,idx_integer) = am%count_psh(cp_t,idx_integer) + 1
1073 
1074  docp = 1
1075  if (am%check_st_integer) then
1076  docp = am%st_integer(cp_t,am%count_psh(cp_t,idx_integer))
1077  endif
1078 
1079  if (docp == 1) then
1080  am%index_psh(cp_t,idx_integer) = am%index_psh(cp_t,idx_integer) + dimen
1081  am%cp_integer(cp_t,am%index_psh(cp_t,idx_integer)-dimen+1:am%index_psh(cp_t,idx_integer)) = field
1082  endif
1083 
1084  endif
1085 
1086  end subroutine psh_integer_k1
1087 
1088 ! popinteger
1089 ! -----------
1090 
1091  subroutine pop_integer_k0(field,skip)
1093  implicit none
1094 
1095  integer, intent(inout) :: field
1096  logical, optional, intent(in) :: skip
1097  integer :: tmp
1098  logical :: skipcp
1099  integer(status_kind) :: docp
1100 
1101  skipcp = .false.
1102  if (present(skip)) then
1103  skipcp = skip
1104  endif
1105 
1106  if (cp_i == 0) then
1107 
1108  if(.not.skipcp) CALL popinteger4(field)
1109 
1110  elseif (cp_i == 1 .or. cp_i == 2) then
1111 
1112  if (cp_i == 1) am%count_pop(cp_t,idx_integer) = am%count_pop(cp_t,idx_integer) + 1
1113 
1114  if (am%check_st_integer .and. cp_i == 2 .and. am%recording) tmp = field
1115 
1116  if(.not.skipcp) CALL popinteger4(field)
1117 
1118  if (am%check_st_integer .and. cp_i == 2 .and. am%recording) then
1119  if ((field - tmp == 0)) then
1120  am%st_integer(cp_t,am%count_pop(cp_t,idx_integer)) = 0
1121  am%index_pop(cp_t,idx_integer) = am%index_pop(cp_t,idx_integer) - 1
1122  elseif (field == 0) then
1123  am%st_integer(cp_t,am%count_pop(cp_t,idx_integer)) = -1
1124  am%index_pop(cp_t,idx_integer) = am%index_pop(cp_t,idx_integer) - 1
1125  endif
1126  am%count_pop(cp_t,idx_integer) = am%count_pop(cp_t,idx_integer) - 1
1127  endif
1128 
1129  elseif (cp_i >= 3) then
1130 
1131  docp = 1
1132  if (am%check_st_integer) then
1133  docp = am%st_integer(cp_t,am%count_pop(cp_t,idx_integer))
1134  endif
1135  am%count_pop(cp_t,idx_integer) = am%count_pop(cp_t,idx_integer) - 1
1136 
1137  if (docp == 1) then
1138  field = am%cp_integer(cp_t,am%index_pop(cp_t,idx_integer))
1139  am%index_pop(cp_t,idx_integer) = am%index_pop(cp_t,idx_integer) - 1
1140  elseif (docp == -1) then
1141  field = 0
1142  endif
1143 
1144  endif
1145 
1146  end subroutine pop_integer_k0
1147 
1148  subroutine pop_integer_k1(field,dimen,skip)
1150  implicit none
1151 
1152  integer, intent(in) :: dimen
1153  integer, intent(inout) :: field(dimen)
1154  logical, optional, intent(in) :: skip
1155  integer :: tmp(dimen)
1156  logical :: skipcp
1157  integer(status_kind) :: docp
1158 
1159  skipcp = .false.
1160  if (present(skip)) then
1161  skipcp = skip
1162  endif
1163 
1164  if (cp_i == 0) then
1165 
1166  if(.not.skipcp) CALL popinteger4array(field,dimen)
1167 
1168  elseif (cp_i == 1 .or. cp_i == 2) then
1169 
1170  if (cp_i == 1) am%count_pop(cp_t,idx_integer) = am%count_pop(cp_t,idx_integer) + 1
1171 
1172  if (am%check_st_integer .and. cp_i == 2 .and. am%recording) tmp = field
1173 
1174  if(.not.skipcp) CALL popinteger4array(field,dimen)
1175 
1176  if (am%check_st_integer .and. cp_i == 2 .and. am%recording) then
1177  if (maxval(abs(field - tmp)) == 0) then
1178  am%st_integer(cp_t,am%count_pop(cp_t,idx_integer)) = 0
1179  am%index_pop(cp_t,idx_integer) = am%index_pop(cp_t,idx_integer) - dimen
1180  elseif (maxval(abs(field)) == 0) then
1181  am%st_integer(cp_t,am%count_pop(cp_t,idx_integer)) = -1
1182  am%index_pop(cp_t,idx_integer) = am%index_pop(cp_t,idx_integer) - dimen
1183  endif
1184  am%count_pop(cp_t,idx_integer) = am%count_pop(cp_t,idx_integer) - 1
1185  endif
1186 
1187  elseif (cp_i >= 3) then
1188 
1189  docp = 1
1190  if (am%check_st_integer) then
1191  docp = am%st_integer(cp_t,am%count_pop(cp_t,idx_integer))
1192  endif
1193  am%count_pop(cp_t,idx_integer) = am%count_pop(cp_t,idx_integer) - 1
1194 
1195  if (docp == 1) then
1196  field = am%cp_integer(cp_t,am%index_pop(cp_t,idx_integer)-dimen+1:am%index_pop(cp_t,idx_integer))
1197  am%index_pop(cp_t,idx_integer) = am%index_pop(cp_t,idx_integer) - dimen
1198  elseif (docp == -1) then
1199  field = 0
1200  endif
1201 
1202  endif
1203 
1204  end subroutine pop_integer_k1
1205 
1206 ! pushrealarray - r4
1207 ! ------------------
1208 
1209  subroutine psh_real_r4_k0(field,skip)
1211  implicit none
1212 
1213  real(4), intent(in) :: field
1214  logical, optional, intent(in) :: skip
1215  logical :: skipcp
1216  integer(status_kind) :: docp
1217 
1218  skipcp = .false.
1219  if (present(skip)) then
1220  skipcp = skip
1221  endif
1222 
1223  if (cp_i == 0) then
1224 
1225  if(.not.skipcp) CALL pushreal4(field)
1226 
1227  elseif (cp_i == 1 .or. cp_i == 2) then
1228 
1229  if (am%recording) then
1230  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1231  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + 1
1232  endif
1233 
1234  if(.not.skipcp) CALL pushreal4(field)
1235 
1236  elseif (cp_i == 3 .and. am%recording) then
1237 
1238  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1239 
1240  docp = 1
1241  if (am%check_st_real_r4) then
1242  docp = am%st_real_r4(cp_t,am%count_psh(cp_t,idx_real_r4))
1243  endif
1244 
1245  if (docp == 1) then
1246  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + 1
1247  am%cp_real_r4(cp_t,am%index_psh(cp_t,idx_real_r4)) = field
1248  endif
1249 
1250  endif
1251 
1252  end subroutine psh_real_r4_k0
1253 
1254  subroutine psh_real_r4_k1(field,dimen,skip)
1256  implicit none
1257 
1258  integer, intent(in) :: dimen
1259  real(4), intent(in) :: field(dimen)
1260  logical, optional, intent(in) :: skip
1261  logical :: skipcp
1262  integer(status_kind) :: docp
1263 
1264  skipcp = .false.
1265  if (present(skip)) then
1266  skipcp = skip
1267  endif
1268 
1269  if (cp_i == 0) then
1270 
1271  if(.not.skipcp) CALL pushreal4array(field,dimen)
1272 
1273  elseif (cp_i == 1 .or. cp_i == 2) then
1274 
1275  if (am%recording) then
1276  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1277  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1278  endif
1279 
1280  if(.not.skipcp) CALL pushreal4array(field,dimen)
1281 
1282  elseif (cp_i == 3 .and. am%recording) then
1283 
1284  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1285 
1286  docp = 1
1287  if (am%check_st_real_r4) then
1288  docp = am%st_real_r4(cp_t,am%count_psh(cp_t,idx_real_r4))
1289  endif
1290 
1291  if (docp == 1) then
1292  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1293  am%cp_real_r4(cp_t,am%index_psh(cp_t,idx_real_r4)-dimen+1:am%index_psh(cp_t,idx_real_r4)) = field
1294  endif
1295 
1296  endif
1297 
1298  end subroutine psh_real_r4_k1
1299 
1300  subroutine psh_real_r4_k2(field,dimen,skip)
1302  implicit none
1303 
1304  integer, intent(in) :: dimen
1305  real(4), intent(in) :: field(:,:)
1306  logical, optional, intent(in) :: skip
1307  logical :: skipcp
1308  integer(status_kind) :: docp
1309 
1310  skipcp = .false.
1311  if (present(skip)) then
1312  skipcp = skip
1313  endif
1314 
1315  if (cp_i == 0) then
1316 
1317  if(.not.skipcp) CALL pushreal4array(field,dimen)
1318 
1319  elseif (cp_i == 1 .or. cp_i == 2) then
1320 
1321  if (am%recording) then
1322  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1323  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1324  endif
1325 
1326  if(.not.skipcp) CALL pushreal4array(field,dimen)
1327 
1328  elseif (cp_i == 3 .and. am%recording) then
1329 
1330  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1331 
1332  docp = 1
1333  if (am%check_st_real_r4) then
1334  docp = am%st_real_r4(cp_t,am%count_psh(cp_t,idx_real_r4))
1335  endif
1336 
1337  if (docp == 1) then
1338  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1339  am%cp_real_r4(cp_t,am%index_psh(cp_t,idx_real_r4)-dimen+1:am%index_psh(cp_t,idx_real_r4)) = reshape(field,(/dimen/))
1340  endif
1341 
1342  endif
1343 
1344  end subroutine psh_real_r4_k2
1345 
1346  subroutine psh_real_r4_k3(field,dimen,skip)
1348  implicit none
1349 
1350  integer, intent(in) :: dimen
1351  real(4), intent(in) :: field(:,:,:)
1352  logical, optional, intent(in) :: skip
1353  logical :: skipcp
1354  integer(status_kind) :: docp
1355 
1356  skipcp = .false.
1357  if (present(skip)) then
1358  skipcp = skip
1359  endif
1360 
1361  if (cp_i == 0) then
1362 
1363  if(.not.skipcp) CALL pushreal4array(field,dimen)
1364 
1365  elseif (cp_i == 1 .or. cp_i == 2) then
1366 
1367  if (am%recording) then
1368  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1369  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1370  endif
1371 
1372  if(.not.skipcp) CALL pushreal4array(field,dimen)
1373 
1374  elseif (cp_i == 3 .and. am%recording) then
1375 
1376  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1377 
1378  docp = 1
1379  if (am%check_st_real_r4) then
1380  docp = am%st_real_r4(cp_t,am%count_psh(cp_t,idx_real_r4))
1381  endif
1382 
1383  if (docp == 1) then
1384  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1385  am%cp_real_r4(cp_t,am%index_psh(cp_t,idx_real_r4)-dimen+1:am%index_psh(cp_t,idx_real_r4)) = reshape(field,(/dimen/))
1386  endif
1387 
1388  endif
1389 
1390  end subroutine psh_real_r4_k3
1391 
1392  subroutine psh_real_r4_k4(field,dimen,skip)
1394  implicit none
1395 
1396  integer, intent(in) :: dimen
1397  real(4), intent(in) :: field(:,:,:,:)
1398  logical, optional, intent(in) :: skip
1399  logical :: skipcp
1400  integer(status_kind) :: docp
1401 
1402  skipcp = .false.
1403  if (present(skip)) then
1404  skipcp = skip
1405  endif
1406 
1407  if (cp_i == 0) then
1408 
1409  if(.not.skipcp) CALL pushreal4array(field,dimen)
1410 
1411  elseif (cp_i == 1 .or. cp_i == 2) then
1412 
1413  if (am%recording) then
1414  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1415  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1416  endif
1417 
1418  if(.not.skipcp) CALL pushreal4array(field,dimen)
1419 
1420  elseif (cp_i == 3 .and. am%recording) then
1421 
1422  am%count_psh(cp_t,idx_real_r4) = am%count_psh(cp_t,idx_real_r4) + 1
1423 
1424  docp = 1
1425  if (am%check_st_real_r4) then
1426  docp = am%st_real_r4(cp_t,am%count_psh(cp_t,idx_real_r4))
1427  endif
1428 
1429  if (docp == 1) then
1430  am%index_psh(cp_t,idx_real_r4) = am%index_psh(cp_t,idx_real_r4) + dimen
1431  am%cp_real_r4(cp_t,am%index_psh(cp_t,idx_real_r4)-dimen+1:am%index_psh(cp_t,idx_real_r4)) = reshape(field,(/dimen/))
1432  endif
1433 
1434  endif
1435 
1436  end subroutine psh_real_r4_k4
1437 
1438 ! poprealarray - r4
1439 ! -----------------
1440 
1441  subroutine pop_real_r4_k0(field,skip)
1443  implicit none
1444 
1445  real(4), intent(inout) :: field
1446  logical, optional, intent(in) :: skip
1447  real(4) :: tmp
1448  logical :: skipcp
1449  integer(status_kind) :: docp
1450 
1451  skipcp = .false.
1452  if (present(skip)) then
1453  skipcp = skip
1454  endif
1455 
1456  if (cp_i == 0) then
1457 
1458  if(.not.skipcp) CALL popreal4(field)
1459 
1460  elseif (cp_i == 1 .or. cp_i == 2) then
1461 
1462  if (cp_i == 1) am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) + 1
1463 
1464  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) tmp = field
1465 
1466  if(.not.skipcp) CALL popreal4(field)
1467 
1468  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1469  if ((field - tmp == 0.0_4)) then
1470  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = 0
1471  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - 1
1472  elseif (field == 0.0_4) then
1473  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = -1
1474  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - 1
1475  endif
1476  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1477  endif
1478 
1479  elseif (cp_i >= 3) then
1480 
1481  docp = 1
1482  if (am%check_st_real_r4) then
1483  docp = am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4))
1484  endif
1485  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1486 
1487  if (docp == 1) then
1488  if(.not.skipcp) field = am%cp_real_r4(cp_t,am%index_pop(cp_t,idx_real_r4))
1489  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - 1
1490  elseif (docp == -1) then
1491  if(.not.skipcp) field = 0.0_4
1492  endif
1493 
1494  endif
1495 
1496  end subroutine pop_real_r4_k0
1497 
1498  subroutine pop_real_r4_k1(field,dimen,skip)
1500  implicit none
1501 
1502  integer, intent(in) :: dimen
1503  real(4), intent(inout) :: field(dimen)
1504  logical, optional, intent(in) :: skip
1505  real(4), allocatable :: tmp(:)
1506  logical :: skipcp
1507  integer(status_kind) :: docp
1508 
1509  skipcp = .false.
1510  if (present(skip)) then
1511  skipcp = skip
1512  endif
1513 
1514  if (cp_i == 0) then
1515 
1516  if(.not.skipcp) CALL popreal4array(field,dimen)
1517 
1518  elseif (cp_i == 1 .or. cp_i == 2) then
1519 
1520  if (cp_i == 1) am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) + 1
1521 
1522  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1523  allocate(tmp(dimen))
1524  tmp = field
1525  endif
1526 
1527  if(.not.skipcp) CALL popreal4array(field,dimen)
1528 
1529  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1530  if (maxval(abs(field - tmp)) == 0.0_4) then
1531  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = 0
1532  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1533  elseif (maxval(abs(field)) == 0.0_4) then
1534  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = -1
1535  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1536  endif
1537  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1538  deallocate(tmp)
1539  endif
1540 
1541  elseif (cp_i >= 3) then
1542 
1543  docp = 1
1544  if (am%check_st_real_r4) then
1545  docp = am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4))
1546  endif
1547  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1548 
1549  if (docp == 1) then
1550  field = am%cp_real_r4(cp_t,am%index_pop(cp_t,idx_real_r4)-dimen+1:am%index_pop(cp_t,idx_real_r4))
1551  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1552  elseif (docp == -1) then
1553  field = 0.0_4
1554  endif
1555 
1556  endif
1557 
1558  end subroutine pop_real_r4_k1
1559 
1560  subroutine pop_real_r4_k2(field,dimen,skip)
1562  implicit none
1563 
1564  integer, intent(in) :: dimen
1565  real(4), intent(inout) :: field(:,:)
1566  logical, optional, intent(in) :: skip
1567  real(4), allocatable :: tmp(:,:)
1568  logical :: skipcp
1569  integer(status_kind) :: docp
1570 
1571  skipcp = .false.
1572  if (present(skip)) then
1573  skipcp = skip
1574  endif
1575 
1576  if (cp_i == 0) then
1577 
1578  if(.not.skipcp) CALL popreal4array(field,dimen)
1579 
1580  elseif (cp_i == 1 .or. cp_i == 2) then
1581 
1582  if (cp_i == 1) am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) + 1
1583 
1584  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1585  allocate(tmp(dimen,1))
1586  tmp = reshape(field,(/dimen, 1/))
1587  endif
1588 
1589  if(.not.skipcp) CALL popreal4array(field,dimen)
1590 
1591  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1592  if (maxval(abs(tmp - reshape(field,(/dimen, 1/)))) == 0.0_4) then
1593  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = 0
1594  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1595  elseif (maxval(abs(field)) == 0.0_4) then
1596  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = -1
1597  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1598  endif
1599  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1600  deallocate(tmp)
1601  endif
1602 
1603  elseif (cp_i >= 3) then
1604 
1605  docp = 1
1606  if (am%check_st_real_r4) then
1607  docp = am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4))
1608  endif
1609  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1610 
1611  if (docp == 1) then
1612  field = reshape(am%cp_real_r4(cp_t,am%index_pop(cp_t,idx_real_r4)-dimen+1:am%index_pop(cp_t,idx_real_r4)),&
1613  (/size(field,1),size(field,2)/))
1614  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1615  elseif (docp == -1) then
1616  field = 0.0_4
1617  endif
1618 
1619  endif
1620 
1621  end subroutine pop_real_r4_k2
1622 
1623  subroutine pop_real_r4_k3(field,dimen,skip)
1625  implicit none
1626 
1627  integer, intent(in) :: dimen
1628  real(4), intent(inout) :: field(:,:,:)
1629  logical, optional, intent(in) :: skip
1630  real(4), allocatable :: tmp(:,:)
1631  logical :: skipcp
1632  integer(status_kind) :: docp
1633 
1634  skipcp = .false.
1635  if (present(skip)) then
1636  skipcp = skip
1637  endif
1638 
1639  if (cp_i == 0) then
1640 
1641  if(.not.skipcp) CALL popreal4array(field,dimen)
1642 
1643  elseif (cp_i == 1 .or. cp_i == 2) then
1644 
1645  if (cp_i == 1) am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) + 1
1646 
1647  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1648  allocate(tmp(dimen,1))
1649  tmp = reshape(field,(/dimen, 1/))
1650  endif
1651 
1652  if(.not.skipcp) CALL popreal4array(field,dimen)
1653 
1654  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1655  if (maxval(abs(tmp - reshape(field,(/dimen, 1/)))) == 0.0_4) then
1656  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = 0
1657  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1658  elseif (maxval(abs(field)) == 0.0_4) then
1659  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = -1
1660  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1661  endif
1662  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1663  deallocate(tmp)
1664  endif
1665 
1666  elseif (cp_i >= 3) then
1667 
1668  docp = 1
1669  if (am%check_st_real_r4) then
1670  docp = am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4))
1671  endif
1672  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1673 
1674  if (docp == 1) then
1675  field = reshape(am%cp_real_r4(cp_t,am%index_pop(cp_t,idx_real_r4)-dimen+1:am%index_pop(cp_t,idx_real_r4)),&
1676  (/size(field,1),size(field,2),size(field,3)/))
1677  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1678  elseif (docp == -1) then
1679  field = 0.0_4
1680  endif
1681 
1682  endif
1683 
1684  end subroutine pop_real_r4_k3
1685 
1686  subroutine pop_real_r4_k4(field,dimen,skip)
1688  implicit none
1689 
1690  integer, intent(in) :: dimen
1691  real(4), intent(inout) :: field(:,:,:,:)
1692  logical, optional, intent(in) :: skip
1693  real(4), allocatable :: tmp(:,:)
1694  logical :: skipcp
1695  integer(status_kind) :: docp
1696 
1697  skipcp = .false.
1698  if (present(skip)) then
1699  skipcp = skip
1700  endif
1701 
1702  if (cp_i == 0) then
1703 
1704  if(.not.skipcp) CALL popreal4array(field,dimen)
1705 
1706  elseif (cp_i == 1 .or. cp_i == 2) then
1707 
1708  if (cp_i == 1) am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) + 1
1709 
1710  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1711  allocate(tmp(dimen,1))
1712  tmp = reshape(field,(/dimen, 1/))
1713  endif
1714 
1715  if(.not.skipcp) CALL popreal4array(field,dimen)
1716 
1717  if (am%check_st_real_r4 .and. cp_i == 2 .and. am%recording) then
1718  if (maxval(abs(tmp - reshape(field,(/dimen, 1/)))) == 0.0_4) then
1719  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = 0
1720  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1721  elseif (maxval(abs(field)) == 0.0_4) then
1722  am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4)) = -1
1723  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1724  endif
1725  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1726  deallocate(tmp)
1727  endif
1728 
1729  elseif (cp_i >= 3) then
1730 
1731  docp = 1
1732  if (am%check_st_real_r4) then
1733  docp = am%st_real_r4(cp_t,am%count_pop(cp_t,idx_real_r4))
1734  endif
1735  am%count_pop(cp_t,idx_real_r4) = am%count_pop(cp_t,idx_real_r4) - 1
1736 
1737  if (docp == 1) then
1738  field = reshape(am%cp_real_r4(cp_t,am%index_pop(cp_t,idx_real_r4)-dimen+1:am%index_pop(cp_t,idx_real_r4)),&
1739  (/size(field,1),size(field,2),size(field,3),size(field,4)/))
1740  am%index_pop(cp_t,idx_real_r4) = am%index_pop(cp_t,idx_real_r4) - dimen
1741  elseif (docp == -1) then
1742  field = 0.0_4
1743  endif
1744 
1745  endif
1746 
1747  end subroutine pop_real_r4_k4
1748 
1749 ! pushrealarray - r8
1750 ! ------------------
1751 
1752  subroutine psh_real_r8_k0(field,skip)
1754  implicit none
1755 
1756  real(8), intent(in) :: field
1757  logical, optional, intent(in) :: skip
1758  logical :: skipcp
1759  integer(status_kind) :: docp
1760 
1761  skipcp = .false.
1762  if (present(skip)) then
1763  skipcp = skip
1764  endif
1765 
1766  if (cp_i == 0) then
1767 
1768  if(.not.skipcp) CALL pushreal8(field)
1769 
1770  elseif (cp_i == 1 .or. cp_i == 2) then
1771 
1772  if (am%recording) then
1773  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1774  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + 1
1775  endif
1776 
1777  if(.not.skipcp) CALL pushreal8(field)
1778 
1779  elseif (cp_i == 3 .and. am%recording) then
1780 
1781  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1782 
1783  docp = 1
1784  if (am%check_st_real_r8) then
1785  docp = am%st_real_r8(cp_t,am%count_psh(cp_t,idx_real_r8))
1786  endif
1787 
1788  if (docp == 1) then
1789  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + 1
1790  am%cp_real_r8(cp_t,am%index_psh(cp_t,idx_real_r8)) = field
1791  endif
1792 
1793  endif
1794 
1795  end subroutine psh_real_r8_k0
1796 
1797  subroutine psh_real_r8_k1(field,dimen,skip)
1799  implicit none
1800 
1801  integer, intent(in) :: dimen
1802  real(8), intent(in) :: field(dimen)
1803  logical, optional, intent(in) :: skip
1804  logical :: skipcp
1805  integer(status_kind) :: docp
1806 
1807  skipcp = .false.
1808  if (present(skip)) then
1809  skipcp = skip
1810  endif
1811 
1812  if (cp_i == 0) then
1813 
1814  if(.not.skipcp) CALL pushreal8array(field,dimen)
1815 
1816  elseif (cp_i == 1 .or. cp_i == 2) then
1817 
1818  if (am%recording) then
1819  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1820  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1821  endif
1822 
1823  if(.not.skipcp) CALL pushreal8array(field,dimen)
1824 
1825  elseif (cp_i == 3 .and. am%recording) then
1826 
1827  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1828 
1829  docp = 1
1830  if (am%check_st_real_r8) then
1831  docp = am%st_real_r8(cp_t,am%count_psh(cp_t,idx_real_r8))
1832  endif
1833 
1834  if (docp == 1) then
1835  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1836  am%cp_real_r8(cp_t,am%index_psh(cp_t,idx_real_r8)-dimen+1:am%index_psh(cp_t,idx_real_r8)) = field
1837  endif
1838 
1839  endif
1840 
1841  end subroutine psh_real_r8_k1
1842 
1843  subroutine psh_real_r8_k2(field,dimen,skip)
1845  implicit none
1846 
1847  integer, intent(in) :: dimen
1848  real(8), intent(in) :: field(:,:)
1849  logical, optional, intent(in) :: skip
1850  logical :: skipcp
1851  integer(status_kind) :: docp
1852 
1853  skipcp = .false.
1854  if (present(skip)) then
1855  skipcp = skip
1856  endif
1857 
1858  if (cp_i == 0) then
1859 
1860  if(.not.skipcp) CALL pushreal8array(field,dimen)
1861 
1862  elseif (cp_i == 1 .or. cp_i == 2) then
1863 
1864  if (am%recording) then
1865  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1866  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1867  endif
1868 
1869  if(.not.skipcp) CALL pushreal8array(field,dimen)
1870 
1871  elseif (cp_i == 3 .and. am%recording) then
1872 
1873  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1874 
1875  docp = 1
1876  if (am%check_st_real_r8) then
1877  docp = am%st_real_r8(cp_t,am%count_psh(cp_t,idx_real_r8))
1878  endif
1879 
1880  if (docp == 1) then
1881  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1882  am%cp_real_r8(cp_t,am%index_psh(cp_t,idx_real_r8)-dimen+1:am%index_psh(cp_t,idx_real_r8)) = reshape(field,(/dimen/))
1883  endif
1884 
1885  endif
1886 
1887  end subroutine psh_real_r8_k2
1888 
1889  subroutine psh_real_r8_k3(field,dimen,skip)
1891  implicit none
1892 
1893  integer, intent(in) :: dimen
1894  real(8), intent(in) :: field(:,:,:)
1895  logical, optional, intent(in) :: skip
1896  logical :: skipcp
1897  integer(status_kind) :: docp
1898 
1899  skipcp = .false.
1900  if (present(skip)) then
1901  skipcp = skip
1902  endif
1903 
1904  if (cp_i == 0) then
1905 
1906  if(.not.skipcp) CALL pushreal8array(field,dimen)
1907 
1908  elseif (cp_i == 1 .or. cp_i == 2) then
1909 
1910  if (am%recording) then
1911  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1912  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1913  endif
1914 
1915  if(.not.skipcp) CALL pushreal8array(field,dimen)
1916 
1917  elseif (cp_i == 3 .and. am%recording) then
1918 
1919  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1920 
1921  docp = 1
1922  if (am%check_st_real_r8) then
1923  docp = am%st_real_r8(cp_t,am%count_psh(cp_t,idx_real_r8))
1924  endif
1925 
1926  if (docp == 1) then
1927  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1928  am%cp_real_r8(cp_t,am%index_psh(cp_t,idx_real_r8)-dimen+1:am%index_psh(cp_t,idx_real_r8)) = reshape(field,(/dimen/))
1929  endif
1930 
1931  endif
1932 
1933  end subroutine psh_real_r8_k3
1934 
1935  subroutine psh_real_r8_k4(field,dimen,skip)
1937  implicit none
1938 
1939  integer, intent(in) :: dimen
1940  real(8), intent(in) :: field(:,:,:,:)
1941  logical, optional, intent(in) :: skip
1942  logical :: skipcp
1943  integer(status_kind) :: docp
1944 
1945  skipcp = .false.
1946  if (present(skip)) then
1947  skipcp = skip
1948  endif
1949 
1950  if (cp_i == 0) then
1951 
1952  if(.not.skipcp) CALL pushreal8array(field,dimen)
1953 
1954  elseif (cp_i == 1 .or. cp_i == 2) then
1955 
1956  if (am%recording) then
1957  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1958  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1959  endif
1960 
1961  if(.not.skipcp) CALL pushreal8array(field,dimen)
1962 
1963  elseif (cp_i == 3 .and. am%recording) then
1964 
1965  am%count_psh(cp_t,idx_real_r8) = am%count_psh(cp_t,idx_real_r8) + 1
1966 
1967  docp = 1
1968  if (am%check_st_real_r8) then
1969  docp = am%st_real_r8(cp_t,am%count_psh(cp_t,idx_real_r8))
1970  endif
1971 
1972  if (docp == 1) then
1973  am%index_psh(cp_t,idx_real_r8) = am%index_psh(cp_t,idx_real_r8) + dimen
1974  am%cp_real_r8(cp_t,am%index_psh(cp_t,idx_real_r8)-dimen+1:am%index_psh(cp_t,idx_real_r8)) = reshape(field,(/dimen/))
1975  endif
1976 
1977  endif
1978 
1979  end subroutine psh_real_r8_k4
1980 
1981 ! poprealarray - r8
1982 ! -----------------
1983 
1984  subroutine pop_real_r8_k0(field,skip)
1986  implicit none
1987 
1988  real(8), intent(inout) :: field
1989  logical, optional, intent(in) :: skip
1990  real(8) :: tmp
1991  logical :: skipcp
1992  integer(status_kind) :: docp
1993 
1994  skipcp = .false.
1995  if (present(skip)) then
1996  skipcp = skip
1997  endif
1998 
1999  if (cp_i == 0) then
2000 
2001  if(.not.skipcp) CALL popreal8(field)
2002 
2003  elseif (cp_i == 1 .or. cp_i == 2) then
2004 
2005  if (cp_i == 1) am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) + 1
2006 
2007  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) tmp = field
2008 
2009  if(.not.skipcp) CALL popreal8(field)
2010 
2011  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2012  if ((field - tmp == 0.0_8)) then
2013  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = 0
2014  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - 1
2015  elseif (field == 0.0_8) then
2016  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = -1
2017  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - 1
2018  endif
2019  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2020  endif
2021 
2022  elseif (cp_i >= 3) then
2023 
2024  docp = 1
2025  if (am%check_st_real_r8) then
2026  docp = am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8))
2027  endif
2028  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2029 
2030  if (docp == 1) then
2031  if(.not.skipcp) field = am%cp_real_r8(cp_t,am%index_pop(cp_t,idx_real_r8))
2032  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - 1
2033  elseif (docp == -1) then
2034  if(.not.skipcp) field = 0.0_8
2035  endif
2036 
2037  endif
2038 
2039  end subroutine pop_real_r8_k0
2040 
2041  subroutine pop_real_r8_k1(field,dimen,skip)
2043  implicit none
2044 
2045  integer, intent(in) :: dimen
2046  real(8), intent(inout) :: field(dimen)
2047  logical, optional, intent(in) :: skip
2048  real(8), allocatable :: tmp(:)
2049  logical :: skipcp
2050  integer(status_kind) :: docp
2051 
2052  skipcp = .false.
2053  if (present(skip)) then
2054  skipcp = skip
2055  endif
2056 
2057  if (cp_i == 0) then
2058 
2059  if(.not.skipcp) CALL popreal8array(field,dimen)
2060 
2061  elseif (cp_i == 1 .or. cp_i == 2) then
2062 
2063  if (cp_i == 1) am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) + 1
2064 
2065  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2066  allocate(tmp(dimen))
2067  tmp = field
2068  endif
2069 
2070  if(.not.skipcp) CALL popreal8array(field,dimen)
2071 
2072  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2073  if (maxval(abs(field - tmp)) == 0.0_8) then
2074  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = 0
2075  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2076  elseif (maxval(abs(field)) == 0.0_8) then
2077  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = -1
2078  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2079  endif
2080  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2081  deallocate(tmp)
2082  endif
2083 
2084  elseif (cp_i >= 3) then
2085 
2086  docp = 1
2087  if (am%check_st_real_r8) then
2088  docp = am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8))
2089  endif
2090  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2091 
2092  if (docp == 1) then
2093  field = am%cp_real_r8(cp_t,am%index_pop(cp_t,idx_real_r8)-dimen+1:am%index_pop(cp_t,idx_real_r8))
2094  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2095  elseif (docp == -1) then
2096  field = 0.0_8
2097  endif
2098 
2099  endif
2100 
2101  end subroutine pop_real_r8_k1
2102 
2103  subroutine pop_real_r8_k2(field,dimen,skip)
2105  implicit none
2106 
2107  integer, intent(in) :: dimen
2108  real(8), intent(inout) :: field(:,:)
2109  logical, optional, intent(in) :: skip
2110  real(8), allocatable :: tmp(:,:)
2111  logical :: skipcp
2112  integer(status_kind) :: docp
2113 
2114  skipcp = .false.
2115  if (present(skip)) then
2116  skipcp = skip
2117  endif
2118 
2119  if (cp_i == 0) then
2120 
2121  if(.not.skipcp) CALL popreal8array(field,dimen)
2122 
2123  elseif (cp_i == 1 .or. cp_i == 2) then
2124 
2125  if (cp_i == 1) am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) + 1
2126 
2127  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2128  allocate(tmp(dimen,1))
2129  tmp = reshape(field,(/dimen, 1/))
2130  endif
2131 
2132  if(.not.skipcp) CALL popreal8array(field,dimen)
2133 
2134  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2135  if (maxval(abs(tmp - reshape(field,(/dimen, 1/)))) == 0.0_8) then
2136  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = 0
2137  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2138  elseif (maxval(abs(field)) == 0.0_8) then
2139  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = -1
2140  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2141  endif
2142  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2143  deallocate(tmp)
2144  endif
2145 
2146  elseif (cp_i >= 3) then
2147 
2148  docp = 1
2149  if (am%check_st_real_r8) then
2150  docp = am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8))
2151  endif
2152  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2153 
2154  if (docp == 1) then
2155  field = reshape(am%cp_real_r8(cp_t,am%index_pop(cp_t,idx_real_r8)-dimen+1:am%index_pop(cp_t,idx_real_r8)),&
2156  (/size(field,1),size(field,2)/))
2157  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2158  elseif (docp == -1) then
2159  field = 0.0_8
2160  endif
2161 
2162  endif
2163 
2164  end subroutine pop_real_r8_k2
2165 
2166  subroutine pop_real_r8_k3(field,dimen,skip)
2168  implicit none
2169 
2170  integer, intent(in) :: dimen
2171  real(8), intent(inout) :: field(:,:,:)
2172  logical, optional, intent(in) :: skip
2173  real(8), allocatable :: tmp(:,:)
2174  logical :: skipcp
2175  integer(status_kind) :: docp
2176 
2177  skipcp = .false.
2178  if (present(skip)) then
2179  skipcp = skip
2180  endif
2181 
2182  if (cp_i == 0) then
2183 
2184  if(.not.skipcp) CALL popreal8array(field,dimen)
2185 
2186  elseif (cp_i == 1 .or. cp_i == 2) then
2187 
2188  if (cp_i == 1) am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) + 1
2189 
2190  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2191  allocate(tmp(dimen,1))
2192  tmp = reshape(field,(/dimen, 1/))
2193  endif
2194 
2195  if(.not.skipcp) CALL popreal8array(field,dimen)
2196 
2197  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2198  if (maxval(abs(tmp - reshape(field,(/dimen, 1/)))) == 0.0_8) then
2199  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = 0
2200  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2201  elseif (maxval(abs(field)) == 0.0_8) then
2202  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = -1
2203  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2204  endif
2205  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2206  deallocate(tmp)
2207  endif
2208 
2209  elseif (cp_i >= 3) then
2210 
2211  docp = 1
2212  if (am%check_st_real_r8) then
2213  docp = am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8))
2214  endif
2215  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2216 
2217  if (docp == 1) then
2218  field = reshape(am%cp_real_r8(cp_t,am%index_pop(cp_t,idx_real_r8)-dimen+1:am%index_pop(cp_t,idx_real_r8)),&
2219  (/size(field,1),size(field,2),size(field,3)/))
2220  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2221  elseif (docp == -1) then
2222  field = 0.0_8
2223  endif
2224 
2225  endif
2226 
2227  end subroutine pop_real_r8_k3
2228 
2229  subroutine pop_real_r8_k4(field,dimen,skip)
2231  implicit none
2232 
2233  integer, intent(in) :: dimen
2234  real(8), intent(inout) :: field(:,:,:,:)
2235  logical, optional, intent(in) :: skip
2236  real(8), allocatable :: tmp(:,:)
2237  logical :: skipcp
2238  integer(status_kind) :: docp
2239 
2240  skipcp = .false.
2241  if (present(skip)) then
2242  skipcp = skip
2243  endif
2244 
2245  if (cp_i == 0) then
2246 
2247  if(.not.skipcp) CALL popreal8array(field,dimen)
2248 
2249  elseif (cp_i == 1 .or. cp_i == 2) then
2250 
2251  if (cp_i == 1) am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) + 1
2252 
2253  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2254  allocate(tmp(dimen,1))
2255  tmp = reshape(field,(/dimen, 1/))
2256  endif
2257 
2258  if(.not.skipcp) CALL popreal8array(field,dimen)
2259 
2260  if (am%check_st_real_r8 .and. cp_i == 2 .and. am%recording) then
2261  if (maxval(abs(tmp - reshape(field,(/dimen, 1/)))) == 0.0_8) then
2262  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = 0
2263  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2264  elseif (maxval(abs(field)) == 0.0_8) then
2265  am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8)) = -1
2266  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2267  endif
2268  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2269  deallocate(tmp)
2270  endif
2271 
2272  elseif (cp_i >= 3) then
2273 
2274  docp = 1
2275  if (am%check_st_real_r8) then
2276  docp = am%st_real_r8(cp_t,am%count_pop(cp_t,idx_real_r8))
2277  endif
2278  am%count_pop(cp_t,idx_real_r8) = am%count_pop(cp_t,idx_real_r8) - 1
2279 
2280  if (docp == 1) then
2281  field = reshape(am%cp_real_r8(cp_t,am%index_pop(cp_t,idx_real_r8)-dimen+1:am%index_pop(cp_t,idx_real_r8)),&
2282  (/size(field,1),size(field,2),size(field,3),size(field,4)/))
2283  am%index_pop(cp_t,idx_real_r8) = am%index_pop(cp_t,idx_real_r8) - dimen
2284  elseif (docp == -1) then
2285  field = 0.0_8
2286  endif
2287 
2288  endif
2289 
2290  end subroutine pop_real_r8_k4
2291 
2292 
2293 
2294 ! pushrealarray_adm
2295 ! -----------------
2296 
2297  subroutine psh_adm_real_r4_k0(field)
2299  implicit none
2300  real(4), intent(inout) :: field
2301 
2302  CALL pushreal4(field)
2303 
2304  end subroutine psh_adm_real_r4_k0
2305 
2306  subroutine psh_adm_real_r4_k1(field,dimen)
2308  implicit none
2309  real(4), intent(inout) :: field(:)
2310  integer, intent(in ) :: dimen
2311 
2312  CALL pushreal4array(field(:),dimen)
2313 
2314  end subroutine psh_adm_real_r4_k1
2315 
2316  subroutine psh_adm_real_r4_k2(field,dimen)
2318  implicit none
2319 
2320  real(4), intent(inout) :: field(:,:)
2321  integer, intent(in ) :: dimen
2322 
2323  CALL pushreal4array(field(:,:),dimen)
2324 
2325  end subroutine psh_adm_real_r4_k2
2326 
2327  subroutine psh_adm_real_r4_k3(field,dimen)
2329  implicit none
2330  real(4), intent(inout) :: field(:,:,:)
2331  integer, intent(in ) :: dimen
2332 
2333  CALL pushreal4array(field(:,:,:),dimen)
2334 
2335  end subroutine psh_adm_real_r4_k3
2336 
2337  subroutine psh_adm_real_r4_k4(field,dimen)
2339  implicit none
2340  real(4), intent(inout) :: field(:,:,:,:)
2341  integer, intent(in ) :: dimen
2342 
2343  CALL pushreal4array(field(:,:,:,:),dimen)
2344 
2345  end subroutine psh_adm_real_r4_k4
2346 
2347  subroutine psh_adm_real_r8_k0(field)
2349  implicit none
2350  real(8), intent(inout) :: field
2351 
2352  CALL pushreal8(field)
2353 
2354  end subroutine psh_adm_real_r8_k0
2355 
2356  subroutine psh_adm_real_r8_k1(field,dimen)
2358  implicit none
2359  real(8), intent(inout) :: field(:)
2360  integer, intent(in ) :: dimen
2361 
2362  CALL pushreal8array(field(:),dimen)
2363 
2364  end subroutine psh_adm_real_r8_k1
2365 
2366  subroutine psh_adm_real_r8_k2(field,dimen)
2368  implicit none
2369  real(8), intent(inout) :: field(:,:)
2370  integer, intent(in ) :: dimen
2371 
2372  CALL pushreal8array(field(:,:),dimen)
2373 
2374  end subroutine psh_adm_real_r8_k2
2375 
2376  subroutine psh_adm_real_r8_k3(field,dimen)
2378  implicit none
2379  real(8), intent(inout) :: field(:,:,:)
2380  integer, intent(in ) :: dimen
2381 
2382  CALL pushreal8array(field(:,:,:),dimen)
2383 
2384  end subroutine psh_adm_real_r8_k3
2385 
2386  subroutine psh_adm_real_r8_k4(field,dimen)
2388  implicit none
2389  real(8), intent(inout) :: field(:,:,:,:)
2390  integer, intent(in ) :: dimen
2391 
2392  CALL pushreal8array(field(:,:,:,:),dimen)
2393 
2394  end subroutine psh_adm_real_r8_k4
2395 
2396 
2397 
2398 ! poprealarray
2399 ! -------------
2400 
2401 !These routines are included to provide an abstract layer for real
2402 !number precision when checkpointing the reference state. They allow
2403 !for compile-time precision choice by an end user, rather than at
2404 !the time Tapenade is used to generate the adjont code.
2405 
2406  subroutine pop_adm_real_r4_k0(field)
2408  implicit none
2409 
2410  real(4), intent(inout) :: field
2411 
2412  CALL popreal4(field)
2413 
2414  end subroutine pop_adm_real_r4_k0
2415 
2416  subroutine pop_adm_real_r4_k1(field,dimen)
2418  implicit none
2419 
2420  real(4), intent(inout) :: field(:)
2421  integer, intent(in ) :: dimen
2422 
2423  CALL popreal4array(field(:),dimen)
2424 
2425  end subroutine pop_adm_real_r4_k1
2426 
2427 
2428  subroutine pop_adm_real_r4_k2(field,dimen)
2430  implicit none
2431 
2432  real(4), intent(inout) :: field(:,:)
2433  integer, intent(in ) :: dimen
2434 
2435  CALL popreal4array(field(:,:),dimen)
2436 
2437  end subroutine pop_adm_real_r4_k2
2438 
2439 
2440  subroutine pop_adm_real_r4_k3(field,dimen)
2442  implicit none
2443 
2444  real(4), intent(inout) :: field(:,:,:)
2445  integer, intent(in ) :: dimen
2446 
2447  CALL popreal4array(field(:,:,:),dimen)
2448 
2449  end subroutine pop_adm_real_r4_k3
2450 
2451 
2452  subroutine pop_adm_real_r4_k4(field,dimen)
2454  implicit none
2455 
2456  real(4), intent(inout) :: field(:,:,:,:)
2457  integer, intent(in ) :: dimen
2458 
2459  CALL popreal4array(field(:,:,:,:),dimen)
2460 
2461  end subroutine pop_adm_real_r4_k4
2462 
2463  subroutine pop_adm_real_r8_k0(field)
2465  implicit none
2466 
2467  real(8), intent(inout) :: field
2468 
2469  CALL popreal8(field)
2470 
2471  end subroutine pop_adm_real_r8_k0
2472 
2473  subroutine pop_adm_real_r8_k1(field,dimen)
2475  implicit none
2476 
2477  real(8), intent(inout) :: field(:)
2478  integer, intent(in ) :: dimen
2479 
2480  CALL popreal8array(field(:),dimen)
2481 
2482  end subroutine pop_adm_real_r8_k1
2483 
2484 
2485  subroutine pop_adm_real_r8_k2(field,dimen)
2487  implicit none
2488 
2489  real(8), intent(inout) :: field(:,:)
2490  integer, intent(in ) :: dimen
2491 
2492  CALL popreal8array(field(:,:),dimen)
2493 
2494  end subroutine pop_adm_real_r8_k2
2495 
2496 
2497  subroutine pop_adm_real_r8_k3(field,dimen)
2499  implicit none
2500 
2501  real(8), intent(inout) :: field(:,:,:)
2502  integer, intent(in ) :: dimen
2503 
2504  CALL popreal8array(field(:,:,:),dimen)
2505 
2506  end subroutine pop_adm_real_r8_k3
2507 
2508 
2509  subroutine pop_adm_real_r8_k4(field,dimen)
2511  implicit none
2512 
2513  real(8), intent(inout) :: field(:,:,:,:)
2514  integer, intent(in ) :: dimen
2515 
2516  CALL popreal8array(field(:,:,:,:),dimen)
2517 
2518  end subroutine pop_adm_real_r8_k4
2519 
2520 endmodule tapenade_iter
subroutine pop_adm_real_r8_k3(field, dimen)
subroutine pop_adm_real_r4_k3(field, dimen)
subroutine pushcontrol5b(cc)
Definition: adBuffer.f:233
subroutine psh_real_r8_k2(field, dimen, skip)
subroutine popinteger4(x)
Definition: adBuffer.f:541
subroutine pop_adm_real_r8_k0(field)
subroutine popcontrol2b(cc)
Definition: adBuffer.f:146
integer(8), dimension(total_types) count_psh_mid
subroutine pop_real_r8_k0(field, skip)
void popinteger4array(int *x, int n)
Definition: adStack.c:335
void popreal8array(double *x, int n)
Definition: adStack.c:375
subroutine pop_real_r4_k4(field, dimen, skip)
integer, pointer cp_nm
type(cp_iter_controls_type), target, public cp_iter_controls
subroutine, public pushcontrol(ctype, field)
subroutine pop_real_r4_k3(field, dimen, skip)
integer, pointer cp_t
logical, save root_pe
subroutine, public cp_mod_ini(cp_mod_index)
subroutine psh_real_r4_k4(field, dimen, skip)
subroutine psh_integer_k0(field, skip)
subroutine psh_adm_real_r4_k2(field, dimen)
subroutine psh_real_r8_k1(field, dimen, skip)
subroutine psh_adm_real_r4_k0(field)
subroutine psh_real_r4_k3(field, dimen, skip)
real(8), parameter b2mb
logical, save cp_iter_finalized
subroutine pushcontrol1b(cc)
Definition: adBuffer.f:115
subroutine psh_real_r8_k4(field, dimen, skip)
subroutine, public cp_mod_mid
subroutine psh_adm_real_r4_k1(field, dimen)
subroutine psh_adm_real_r8_k4(field, dimen)
void pushinteger4array(int *x, int n)
Definition: adStack.c:332
subroutine pushcontrol2b(cc)
Definition: adBuffer.f:140
subroutine, public cp_mod_end
integer, parameter status_kind
void pushreal8array(double *x, int n)
Definition: adStack.c:372
subroutine psh_real_r4_k1(field, dimen, skip)
subroutine popreal8(x)
Definition: adBuffer.f:820
void pushreal4array(float *x, int n)
Definition: adStack.c:362
subroutine psh_adm_real_r8_k3(field, dimen)
subroutine psh_real_r8_k3(field, dimen, skip)
subroutine popcontrol5b(cc)
Definition: adBuffer.f:242
type(cp_iter_type), dimension(:), allocatable, target, public cp_iter
subroutine pop_adm_real_r4_k1(field, dimen)
subroutine, public finalize_cp_iter
logical, save cp_iter_initialized
integer, parameter idx_real_r8
subroutine psh_integer_k1(field, dimen, skip)
subroutine psh_adm_real_r8_k0(field)
integer, parameter idx_real_r4
real(8), parameter b2gb
subroutine pushreal4(x)
Definition: adBuffer.f:670
subroutine psh_adm_real_r8_k2(field, dimen)
subroutine psh_real_r4_k2(field, dimen, skip)
subroutine pop_integer_k1(field, dimen, skip)
subroutine popcontrol3b(cc)
Definition: adBuffer.f:175
integer, parameter idx_control
subroutine pop_real_r8_k3(field, dimen, skip)
subroutine pushreal8(x)
Definition: adBuffer.f:763
integer, pointer cp_nt
subroutine popcontrol1b(cc)
Definition: adBuffer.f:120
subroutine pop_real_r4_k1(field, dimen, skip)
subroutine psh_adm_real_r4_k3(field, dimen)
subroutine psh_real_r4_k0(field, skip)
subroutine pop_adm_real_r4_k4(field, dimen)
subroutine popcontrol4b(cc)
Definition: adBuffer.f:207
subroutine pop_real_r4_k0(field, skip)
integer, pointer cp_i
subroutine psh_adm_real_r8_k1(field, dimen)
subroutine pushcontrol4b(cc)
Definition: adBuffer.f:199
subroutine pop_real_r8_k1(field, dimen, skip)
integer, parameter total_types
subroutine pop_adm_real_r4_k0(field)
subroutine pop_real_r8_k4(field, dimen, skip)
type(cp_iter_type), pointer am
subroutine, public initialize_cp_iter
subroutine pop_adm_real_r8_k1(field, dimen)
subroutine pop_real_r8_k2(field, dimen, skip)
subroutine pop_integer_k0(field, skip)
subroutine pop_adm_real_r4_k2(field, dimen)
subroutine pushcontrol3b(cc)
Definition: adBuffer.f:168
subroutine pop_real_r4_k2(field, dimen, skip)
subroutine psh_adm_real_r4_k4(field, dimen)
integer, parameter idx_integer
subroutine pop_adm_real_r8_k4(field, dimen)
subroutine psh_real_r8_k0(field, skip)
subroutine, public popcontrol(ctype, field)
real, pointer cp_gb
void popreal4array(float *x, int n)
Definition: adStack.c:365
subroutine pushinteger4(x)
Definition: adBuffer.f:484
subroutine pop_adm_real_r8_k2(field, dimen)
subroutine popreal4(x)
Definition: adBuffer.f:727