Initialise message passing, open the input file, split the communicator if running in list mode or if nensembles > 1, initialize the timers. After calling this function, gs2 reaches init\%level = basic. If it is desired to provide an external commuicator or set the input file name externally, these should be set before calling this function.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(gs2_program_state_type), | intent(inout) | :: | state | |||
type(standard_header_type), | intent(in), | optional | :: | header_in |
Header for files with build and run information |
|
type(standard_header_type), | intent(out), | optional | :: | header_out |
Get the header set by this function. Useful if |
|
logical, | intent(in), | optional | :: | quiet |
If true, don't print start-up messages/header |
subroutine initialize_gs2(state, header_in, header_out, quiet)
use file_utils, only: init_file_utils, run_name, run_name_target
use gs2_init, only: init_gs2_init
use job_manage, only: time_message, job_fork
use job_manage, only: init_checktime
use mp, only: init_mp, broadcast, job, iproc, nproc, proc0
use mp, only: use_nproc, included, mp_comm, mp_comm_null
use redistribute, only: using_measure_scatter
use unit_tests, only: debug_message, set_job_id
use standard_header, only: standard_header_type
use optionals, only: get_option_with_default
#ifdef OPENMP
use omp_lib, only: omp_get_num_threads
#endif
implicit none
type(gs2_program_state_type), intent(inout) :: state
!> Header for files with build and run information
type(standard_header_type), intent(in), optional :: header_in
!> Get the header set by this function. Useful if `header_in` is _not_ used
type(standard_header_type), intent(out), optional :: header_out
!> If true, don't print start-up messages/header
logical, intent(in), optional :: quiet
! Actual value for optional `header` input
type(standard_header_type) :: local_header
! Internal value for optional `quiet` input
logical :: quiet_value
#ifdef OPENMP
integer :: nthread
#endif
if (state%init%level .ge. init_level_list%basic) then
write (*,*) "ERROR: Called initialize_gs2 twice &
& without calling finalize_gs2"
stop 1
end if
call debug_message(4, 'gs2_main::initialize_gs2 starting initialization')
call init_mp(state%mp_comm)
if (present(header_in)) then
local_header = header_in
else
local_header = standard_header_type()
end if
if (present(header_out)) header_out = local_header
quiet_value = get_option_with_default(quiet, .false.)
call initialize_wall_clock_timer
! If optimisations say to use a subset of available processors
! create the communicator for this here.
if (state%init%opt_ov%is_initialised() .and. state%init%opt_ov%override_nproc &
.and. state%init%opt_ov%nproc /= nproc) then
state%init%opt_ov%old_comm = mp_comm
call use_nproc(state%init%opt_ov%nproc)
else
state%init%opt_ov%old_comm = mp_comm_null
end if
state%included = included
state%nproc_actual = nproc
if (.not. state%included) return
if (state%is_trinity_job) state%is_external_job = .true.
if (state%is_external_job) then
call broadcast(state%external_job_id)
call set_job_id(state%external_job_id)
end if
call debug_message(state%verb, 'gs2_main::initialize_gs2 initialized mp')
call reset_timers(state%timers)
call init_checktime ! <doc> Initialize timer </doc>
call debug_message(state%verb, &
'gs2_main::initialize_gs2 called init_checktime')
if (proc0) then
! Report number of processors being used
if (.not. quiet_value) then
write(*, '(a)') local_header%to_string(comment_character=" ")
if (state%external_job_id >= 0) then
write(*, '(a, i0, a)', advance="no") "External job ", state%external_job_id, " "
end if
write(*, '(a, i0, a)', advance="no") "Running on ", nproc, " processor"
! Pluralise processor
if (nproc > 1) write(*, '(a)', advance="no") "s"
#ifdef OPENMP
!$OMP PARALLEL
nthread = omp_get_num_threads()
!$OMP END PARALLEL
write(*, '(A, I0, A)',advance="no") " with ", nthread, " thread"
! Pluralise thread
if (nthread > 1) write(*, '(a)', advance="no") "s"
#endif
! Make sure we still get a blank line
write(*,*) new_line('a')
end if
! Call init_file_utils, ie. initialize the run_name, checking
! whether we are doing a Trinity run or a list of runs.
! Until the logic of init_file_utils is fixed we set trin_run
! when an external file name has been provided... this prevents
! it overriding the name from the command line.
call init_file_utils (state%list, trin_run=state%run_name_external, &
name=state%run_name, n_ensembles=state%nensembles)
call debug_message(state%verb, 'gs2_main::initialize_gs2 initialized file_utils')
end if
call broadcast (state%list)
call debug_message(state%verb, 'gs2_main::initialize_gs2 broadcasted list')
if (state%list) then
call job_fork
call set_job_id(job)
call debug_message(state%verb, 'gs2_main::initialize_gs2 called job fork')
else if (state%nensembles > 1) then
call job_fork (n_ensembles=state%nensembles)
call debug_message(state%verb, &
'gs2_main::initialize_gs2 called job fork (nensembles>1)')
end if
call time_message(.false.,state%timers%total,' Total')
! Pass run name to other procs
if (proc0) run_name_target = trim(run_name)
call broadcast (run_name_target)
if (.not. proc0) run_name => run_name_target
call debug_message(state%verb, 'gs2_main::initialize_gs2 run_name = '//run_name)
!Set using_measure_scatter to indicate we want to use in "gather/scatter" timings
using_measure_scatter = .false.
! Initialize the gs2 initialization system
call init_gs2_init()
state%init%level = init_level_list%basic
call time_message(.false.,state%timers%total,' Total')
call debug_message(state%verb, 'gs2_main::initialize_gs2 finished')
end subroutine initialize_gs2