C $Header: /u/gcmpack/MITgcm/eesupp/src/eeset_parms.F,v 1.48 2017/08/10 15:30:19 mlosch Exp $
C $Name: $
#include "CPP_EEOPTIONS.h"
CBOP
C !ROUTINE: EESET_PARMS
C !INTERFACE:
SUBROUTINE EESET_PARMS ( procId, doReport )
C !DESCRIPTION:
C *==========================================================*
C | SUBROUTINE EESET\_PARMS
C | o Routine to set model "parameters"
C *==========================================================*
C | This routine is called from the high-level wrapper
C | after multi-process paralle processing has started but
C | before multi-threaded parallelism. THe routine reads an
C | an "execution environment" input parameter file holding
C | information about the number of threads at run-time.
C *==========================================================*
C !USES:
IMPLICIT NONE
C == Global variables ==
#include "SIZE.h"
#include "EEPARAMS.h"
#include "EESUPPORT.h"
#include "EXCH.h"
C !INPUT PARAMETERS:
C procId :: this process id. number (either in World or in Model)
C doReport :: if false, skip error stop and any report to std-out/err
INTEGER procId
LOGICAL doReport
C !FUNCTIONS:
INTEGER IFNBLNK
EXTERNAL
INTEGER ILNBLNK
EXTERNAL
C !LOCAL VARIABLES:
C == Local variables ==
C iUnit :: Work variable for IO unit number
C errIO :: IO unit error flag
C IL :: Temp. for index strings
C msgBuf :: Temp. for textual I/O
C record :: Temp. for textual I/O
INTEGER IL
INTEGER errIO
INTEGER iUnit
CHARACTER*(MAX_LEN_MBUF) msgBuf
CHARACTER*(MAX_LEN_PREC) record
# if !defined(USE_FORTRAN_SCRATCH_FILES) || defined(SINGLE_DISK_IO)
CHARACTER*(MAX_LEN_FNAM) scratchFile1
CHARACTER*(MAX_LEN_FNAM) scratchFile2
#endif
#ifdef SINGLE_DISK_IO
C mpiRC :: Error code reporting variable used with MPI.
INTEGER mpiRC
#endif
CEOP
NAMELIST //EEPARMS
& nTx, nTy, usingMPI,
& useCubedSphereExchange,
& useCoupler, useNEST_PARENT, useNEST_CHILD, useOASIS,
& useSETRLSTK, useSIGREG,
& debugMode, printMapIncludesZeros, maxLengthPrt1D
C-- For now these options are fixed as the code does not fully support
C features for overlapping communication and computation.
usingSyncMessages = .TRUE.
C-- The remaining parameters here are set to default values; and then
C-- any different values are read from an input file called "eedata".
C The defaults set here are for serial execution.
C
C nTx and nTy are the number of threads in the X and Y directions.
C nSx/nTx and nSy/nTy be whole numbers at present.
C
C notUsingXPeriodicity and notUsingYPeriodicity affect the identifying
C of neighbor processes in a multi-process mode.
C On the whole the numerical model code should not customise itself based
C on these numbers as they may be removed if they do not prove useful.
C
C usingMPI is a flag which controls whether MPI message passing library
C calls are actually made. Note that under MPI it is necessary to start
C a program a special way - normally using a command of the form
C % mpirun program_name
C If usingMPI is set to TRUE but % mpirun .... was not used to launch
C the program then an internal MPI error may be generated when the first
C MPI call ( CALL MPI_Init ) is made.
C
C useCoupler is a flag which controls communications with other
C model components through a coupler interface.
C
C useSETRLSTK is a flag which toggles calling a small C routine
C which sets the stack size to "unlimited" using setrlimit()
notUsingXPeriodicity = .FALSE.
notUsingYPeriodicity = .FALSE.
useCubedSphereExchange = .FALSE.
#ifdef ALLOW_USE_MPI
usingMPI = .TRUE.
#else
usingMPI = .FALSE.
#endif
useCoupler = .FALSE.
useNEST_PARENT = .FALSE.
useNEST_CHILD = .FALSE.
useOASIS = .FALSE.
nTx = 1
nTy = 1
useSETRLSTK = .FALSE.
useSIGREG = .FALSE.
C-- Parameter for printing (ascii) to Std-Oupt:
C Print debug msg (sequence of S/R calls)
debugMode = .FALSE.
C Text map plots of fields ignore exact zero values
printMapIncludesZeros = .FALSE.
C Maximum length for printing (to Std-Msg-Unit) 1-D array
maxLengthPrt1D = 65
C To write output to global-files and from Master MPI process only
C NOTE: read from main parameter file "data"
useSingleCpuIO = .FALSE.
C-- Read in data from eedata file
C We really ought to be using our environment file reading
C package - but we have not written it yet.
C Make scratch copies of input data file with and without comments
#ifdef SINGLE_DISK_IO
C Stop if called from eeboot_minimal.F before myProcId is set
IF ( .NOT.doReport )
& STOP 'ABNORMAL END: S/R EESET_PARMS: myProcId unset'
WRITE(scratchFile1,'(A)') 'scratch1'
WRITE(scratchFile2,'(A)') 'scratch2'
IF( myProcId .EQ. 0 ) THEN
OPEN(UNIT=scrUnit1, FILE=scratchFile1, STATUS='UNKNOWN')
OPEN(UNIT=scrUnit2, FILE=scratchFile2, STATUS='UNKNOWN')
ENDIF
#else /* ifndef SINGLE_DISK_IO */
# ifdef USE_FORTRAN_SCRATCH_FILES
C this is the old default, which can cause filename conflicts on some
C multi-node/multi-processor systems
OPEN(UNIT=scrUnit1,STATUS='SCRATCH')
OPEN(UNIT=scrUnit2,STATUS='SCRATCH')
else
C this definition will go into CPP_EEMACROS.h, once this method is
C properly established
C After opening regular files here, they are closed with STATUS='DELETE'
WRITE(scratchFile1,'(A,'//FMT_PROC_ID//')') 'scratch1.', procId
WRITE(scratchFile2,'(A,'//FMT_PROC_ID//')') 'scratch2.', procId
OPEN(UNIT=scrUnit1, FILE=scratchFile1, STATUS='UNKNOWN')
OPEN(UNIT=scrUnit2, FILE=scratchFile2, STATUS='UNKNOWN')
# endif
#endif /* SINGLE_DISK_IO */
#ifdef SINGLE_DISK_IO
IF( myProcId .EQ. 0 ) THEN
#endif
OPEN(UNIT=eeDataUnit,FILE='eedata',STATUS='OLD',
& err=1,IOSTAT=errIO)
IF ( errIO .GE. 0 ) GOTO 2
1 CONTINUE
IF ( doReport ) THEN
WRITE(msgBuf,'(2A)') 'EESET_PARMS: ',
& 'Unable to open parameter file "eedata"'
CALL PRINT_ERROR( msgBuf, 1 )
CALL EEDATA_EXAMPLE
C note: At this early stage, MPI might not be yet fully set-up; for this reason
C set error flag and return (to avoid a call to ALL_PROC_DIE before stop)
c STOP 'ABNORMAL END: S/R EESET_PARMS'
eeBootError = .TRUE.
ELSE
RETURN
ENDIF
2 CONTINUE
1000 CONTINUE
READ(eeDataUnit,FMT='(A)',END=1001) RECORD
IL = MAX(ILNBLNK(RECORD),1)
IF ( RECORD(1:1) .NE. commentCharacter ) THEN
CALL NML_SET_TERMINATOR( RECORD )
WRITE(UNIT=scrUnit1,FMT='(A)') RECORD(:IL)
ENDIF
WRITE(UNIT=scrUnit2,FMT='(A)') RECORD(:IL)
GOTO 1000
1001 CONTINUE
CLOSE(eeDataUnit)
C-- Report contents of parameter file
iUnit = scrUnit2
IF ( doReport ) THEN
WRITE(msgBuf,'(A)')
& '// ======================================================='
CALL PRINT_MESSAGE(msgBuf, standardMessageUnit, SQUEEZE_RIGHT, 1)
WRITE(msgBuf,'(A)')
& '// Execution Environment parameter file "eedata"'
CALL PRINT_MESSAGE(msgBuf, standardMessageUnit, SQUEEZE_RIGHT, 1)
WRITE(msgBuf,'(A)')
& '// ======================================================='
CALL PRINT_MESSAGE(msgBuf, standardMessageUnit, SQUEEZE_RIGHT, 1)
REWIND(iUnit)
2000 CONTINUE
READ(UNIT=iUnit,FMT='(A)',END=2001) RECORD
IL = MAX(ILNBLNK(RECORD),1)
WRITE(msgBuf,'(A,A)') '>',RECORD(:IL)
CALL PRINT_MESSAGE(msgBuf,standardMessageUnit, SQUEEZE_RIGHT, 1)
GOTO 2000
2001 CONTINUE
WRITE(msgBuf,'(A)') ' '
CALL PRINT_MESSAGE(msgBuf,standardMessageUnit, SQUEEZE_RIGHT, 1)
ENDIF
CLOSE(iUnit,STATUS='DELETE')
#ifdef SINGLE_DISK_IO
CALL FLUSH(scrUnit1)
CLOSE(scrUnit1)
ENDIF
# ifdef ALLOW_USE_MPI
C-- all processes must wait for process 0 to complete
C writing scratchFile1 before opening it
IF ( usingMPI ) THEN
CALL MPI_BARRIER( MPI_COMM_MODEL, mpiRC )
ENDIF
# endif
#ifdef HAVE_SYSTEM
CALL SYSTEM('sleep 1')
#endif
OPEN(UNIT=scrUnit1, FILE=scratchFile1, STATUS='OLD')
#endif /* SINGLE_DISK_IO */
C-- Read namelist
iUnit = scrUnit1
REWIND(iUnit)
READ(UNIT=iUnit,NML=EEPARMS,IOSTAT=errIO,err=3)
IF ( errIO .GE. 0 ) GOTO 4
3 CONTINUE
#ifndef TARGET_PWR3
IF ( doReport ) THEN
WRITE(msgBuf,'(2A)') 'EESET_PARMS: ',
& 'Error reading parameter file "eedata"'
CALL PRINT_ERROR( msgBuf, 1 )
CALL EEDATA_EXAMPLE
eeBootError = .TRUE.
ENDIF
#endif
4 CONTINUE
C-- Execution Environment parameter file read
#ifdef SINGLE_DISK_IO
CLOSE(iUnit)
#else
CLOSE(iUnit,STATUS='DELETE')
#endif /* SINGLE_DISK_IO */
#ifdef ALLOW_USE_MPI
#ifdef ALWAYS_USE_MPI
IF ( doReport .AND. .NOT.usingMPI ) THEN
WRITE(msgBuf,'(2A)') 'EESET_PARMS: ',
& 'in eedata: usingMPI=F conflicts'
CALL PRINT_ERROR( msgBuf, 1 )
WRITE(msgBuf,'(A)') 'EESET_PARMS: with #define ALWAYS_USE_MPI'
CALL PRINT_ERROR( msgBuf, 1 )
eeBootError = .TRUE.
ENDIF
usingMPI = .TRUE.
#endif
#else /* ALLOW_USE_MPI */
IF ( doReport .AND. usingMPI ) THEN
WRITE(msgBuf,'(2A)') 'EESET_PARMS: ',
& 'in eedata: usingMPI=T conflicts'
CALL PRINT_ERROR( msgBuf, 1 )
WRITE(msgBuf,'(A)') 'EESET_PARMS: with #undef ALLOW_USE_MPI'
CALL PRINT_ERROR( msgBuf, 1 )
eeBootError = .TRUE.
ENDIF
usingMPI = .FALSE.
#endif /* ALLOW_USE_MPI */
Cdbg eeDataUnit = 42
Cdbg OPEN(UNIT=eeDataUnit,FILE='eedata',STATUS='OLD',IOSTAT=errIO)
Cdbg IF ( errIO .LT. 0 ) GOTO 11
Cdbg DO K=1, 10
Cdbg READ(eedataUnit,IOSTAT=errIO)
Cdbg IF ( errIO .LT. 0 ) GOTO 11
Cdbg ENDDO
Cdbg READ(eedataUnit,FMT='(30X,1X,L23)',IOSTAT=errIO) notUsingXPeriodicity
Cdbg IF ( errIO .LT. 0 ) GOTO 11
Cdbg READ(eedataUnit,FMT='(30X,1X,L23)',IOSTAT=errIO) notUsingYPeriodicity
Cdbg IF ( errIO .LT. 0 ) GOTO 11
Cdbg READ(eedataUnit,FMT='(30X,1X,L23)',IOSTAT=errIO) usingMPI
Cdbg IF ( errIO .LT. 0 ) GOTO 11
Cdbg READ(eedataUnit,FMT='(30X,1X,I3)',IOSTAT=errIO) nTx
Cdbg IF ( errIO .LT. 0 ) GOTO 11
Cdbg READ(eedataUnit,FMT='(30X,1X,I3)',IOSTAT=errIO) nTy
Cdbg IF (errIO .LT. 0 ) eeBootError = .TRUE.
Cdbg CLOSE(eeDataUnit,IOSTAT=errIO)
Cdbg IF ( eeBootError .OR. errIO .LT. 0 ) THEN
C-- Report that an error occured
Cdbg eeBootError = .TRUE.
Cdbg WRITE(msgBuf,'(A)' )
Cdbg & 'S/R EESET_PARMS: Error reading "eedata" execution environment file'
Cdbg CALL PRINT_ERROR( msgBuf , 1)
Cdbg ELSE
C-- Write summary of settings that were selected
Cdbg ENDIF
IF ( doReport ) THEN
C-- Set parameters for EXCH communication routines
C Note: only done once when called with doReport=T
exchCollectStatistics = .TRUE.
C-- Turn off memsync by default (e.g. needed for threads on SUNs)
exchNeedsMemsync = .TRUE.
exchUsesBarrier = .TRUE.
IF ( usingMPI ) THEN
C-- ... except that MPI needs this until some counter problem is fixed.
exchNeedsMemsync = .FALSE.
exchUsesBarrier = .FALSE.
ENDIF
C-- End setting parameters for EXCH communication routines
ENDIF
RETURN
END