# This script modifies the namelist and finds the best set -ue # Avoid issues with handling floating point numbers export LC_NUMERIC="en_US.UTF-8" SCRIPTPATH=$(readlink -f "`dirname \"$0\"`") # Function to check if the script is executed in a NEMO RUNDIR # The elements checked are the bathymetry, the presence of the namelist_cfg # and the nemo binary that can be called opa or nemo.exe. function in_rundir () { [[ -f bathy_meter.nc ]] && [[ -f opa || -f nemo.exe ]] } # Function to modify namelist parameter function modify_parameter () { [ $# -ne 3 ] && echo "Needed arguments are :" && echo "namelist variable new_value" && return 1 namelist=$1 [ ! -f $namelist ] && echo "ERROR: Namelist $namelist not present" && return 1 var=$2 && value=$3 cond=$( grep -c " $var " $namelist ) [ $cond -eq 0 ] && echo "ERROR: Variable $var not present in namelist $namelist" && return 1 REG="^\( *$var *= *\).*" sed -i "s|$REG|\1$value ! Parameter modified |g " $namelist } # Parameters are: # bathymetry # Max number of processors # Check that file exists binary=$SCRIPTPATH/bin/mpp_domain_decomposition.exe [ ! -f $binary ] && printf "Tool is not configured. Configure it!\n" && exit 1 ldd $binary | grep "not found" -q && echo "ERROR: Must load proper version of NETCDF" && exit 1 # Check the parameters if in_rundir ; then [ $# -ne 1 ] && printf "ELPiN v2\nYou are in a NEMO rundir.\nNeeded parameter is:\nmax_number_of_processes\n" && exit 1 num=$1 && max_num=$( echo "1.05 * $num" | bc -l ) && max_num=$( printf "%.0f\n" "$max_num" ) min_num=$( echo "0.9 * $num" | bc -l ) && min_num=$( printf "%.0f\n" "$min_num" ) # Take parameter and check that file exists bathymetry="bathy_meter.nc" else [ $# -ne 2 ] && printf "ELPiN v2\nNeeded parameters are:\n/path/to/bathymetry\nmax_number_of_processes\n" && exit 1 num=$2 && max_num=$( echo "1.05 * $num" | bc -l ) && max_num=$( printf "%.0f\n" "$max_num" ) min_num=$( echo "0.9 * $num" | bc -l ) && min_num=$( printf "%.0f\n" "$min_num" ) # Take parameter and check that file exists bathymetry=$1 fi [ ! -f $bathymetry ] && echo "Error file does not exist" && exit 1 bathy_checksum=$(md5sum $bathymetry | cut -d" " -f1) # If bathymetry has been already processed if [ -f $SCRIPTPATH/database/$bathy_checksum ]; then # Check that our number of processes falls inside the saved range layout=$SCRIPTPATH/database/$bathy_checksum existing_min=$( grep '%' $layout | awk '{print $5}' | sort -n | head -n 1) existing_max=$( grep '%' $layout | awk '{print $5}' | sort -n | tail -n 1) if [ $num -ge $existing_min ] && [ $num -le $existing_max ]; then CASE_EXIST=TRUE else CASE_EXIST=FALSE fi else CASE_EXIST=FALSE fi # If ELPiN has been already executed for this bathymetry for this number of cores # we simply load the previously generated list if [ "$CASE_EXIST" == "FALSE" ]; then # Read dimensions X=$(ncdump -h $bathymetry | grep "\sx = [0-9]*" -o | grep -e "[0-9]*" -o) Y=$(ncdump -h $bathymetry | grep "\sy = [0-9]*" -o | grep -e "[0-9]*" -o) # Modify the namelist cp $SCRIPTPATH/src/namelist_mpp . # Put bathymetry name in namelist modify_parameter namelist_mpp cbathy "\'$bathymetry\'" # Put grid dimensions modify_parameter namelist_mpp jpiglo $X modify_parameter namelist_mpp jpjglo $Y # Put min and max number of processes modify_parameter namelist_mpp jprocmin $min_num modify_parameter namelist_mpp jprocmax $max_num # Execute Binary. It will generate a file with name expgrid_PEs_decomposition.layout $binary &> /dev/null # Check that the execution completed correctly ERRORCODE=$? if [[ $ERRORCODE -ne 0 ]] ;then echo "Not possible to run dd.x for error $ERRORCODE" exit 1 fi else cp $SCRIPTPATH/database/$bathy_checksum expgrid_PEs_decomposition.layout fi # Process the generated file to find the best decomposition. # Get the best decomposition and split the output into jpnij, jpni and jpnj variables to put it inside the namelist # Get rid of decompositions that need more processes than num DECOMPOSITION_VARS=$( grep "%" expgrid_PEs_decomposition.layout | awk -v maxnum=$num '{ if( $5 <= maxnum ) print $5/($6/100)**2" " $2 " " $3" " $5 }' | sort -n | tail -n 1 | awk '{print $4" "$2" "$3}') jpnij=$(echo $DECOMPOSITION_VARS | cut -d " " -f 1 ) jpni=$(echo $DECOMPOSITION_VARS | cut -d " " -f 2 ) jpnj=$(echo $DECOMPOSITION_VARS | cut -d " " -f 3 ) # If the script is executed in the rundir, it automatically modifies the namelist making first a backup for safety. # Check that the tool is configured properly # This feature is useless right now but can be useful in the future, # by now we will comment this and leave it here. # if in_rundir ; then # cp namelist_cfg namelist_cfg.$(date +%d%m%Y-%H:%M)_backup # modify_parameter namelist_cfg jpnij $jpnij && modify_parameter namelist_cfg jpni $jpni && modify_parameter namelist_cfg jpnj $jpnj || exit 1 # echo "The namelist_cfg has been modified, you must run with $jpnij NEMO processes" # else # echo $jpnij $jpni $jpnj # fi # Output the jpnij jpni and jpnj values echo $jpnij $jpni $jpnj # Copying the list of decompositions to the database named as the checksum. if [ "$CASE_EXIST" == "FALSE" ]; then # In case database folder does not exist, create it [ ! -d $SCRIPTPATH/database ] && mkdir -p $SCRIPTPATH/database cp expgrid_PEs_decomposition.layout $SCRIPTPATH/database/$bathy_checksum fi # Remove the tmp file containing the possible decompositions rm -f expgrid_PEs_decomposition.layout rm -f namelist_mpp set +xuve