76 | | |
| 76 | = Entête des jobs et commandes occigen = |
| 77 | |
| 78 | Cette page décrit les entêtes des jobs sur occigen ainsi que les commandes à lancer pour avoir un exécutable simple ou un couplé (oasis ou XIOS). |
| 79 | |
| 80 | [[PageOutline]] |
| 81 | |
| 82 | == Un executable séquentiel == |
| 83 | * Entête du job |
| 84 | {{{ |
| 85 | #!/bin/bash |
| 86 | #SBATCH -J job_name |
| 87 | #SBATCH -e job_name.e%j |
| 88 | #SBATCH -o job_name.o%j |
| 89 | #SBATCH --nodes=1 |
| 90 | #SBATCH --ntasks=1 |
| 91 | #SBATCH --ntasks-per-node=24 |
| 92 | #SBATCH --threads-per-core=1 |
| 93 | #SBATCH --time=00:10:00 |
| 94 | |
| 95 | }}} |
| 96 | * Commande |
| 97 | {{{ |
| 98 | time ./mon_executable param1 param2 … |
| 99 | }}} |
| 100 | |
| 101 | == Un executable parallélisé avec MPI seulement == |
| 102 | * Entête du job |
| 103 | {{{ |
| 104 | #!/bin/bash |
| 105 | #SBATCH -J job_name |
| 106 | #SBATCH --nodes=2 |
| 107 | #SBATCH --ntasks=48 |
| 108 | #SBATCH --ntasks-per-node=24 |
| 109 | #SBATCH --threads-per-core=1 |
| 110 | #SBATCH --time=00:30:00 |
| 111 | #SBATCH --output job_name.output |
| 112 | }}} |
| 113 | * Commande |
| 114 | {{{ |
| 115 | module purge |
| 116 | module load intel/15.0.0.090 |
| 117 | module load bullxmpi/1.2.8.3 |
| 118 | time srun --mpi=pmi2 -K1 --resv-ports -n $SLURM_NTASKS ./mon_executable param1 param2 … |
| 119 | }}} |
| 120 | |
| 121 | * Résultat : srun lance 48 tâches MPI |
| 122 | |
| 123 | == NEMO MPI seul et XIOS en mode serveur == |
| 124 | * Merci à JMM, DRAKKAR et CINES |
| 125 | * Entête du job |
| 126 | {{{ |
| 127 | #!/bin/bash |
| 128 | #SBATCH --nodes=554 |
| 129 | #SBATCH --ntasks=13296 |
| 130 | #SBATCH --ntasks-per-node=24 |
| 131 | #SBATCH --threads-per-core=1 |
| 132 | #SBATCH -J nemo_occigen |
| 133 | #SBATCH -e nemo_occigen.e%j |
| 134 | #SBATCH -o nemo_occigen.o%j |
| 135 | #SBATCH --time=24:00:00 |
| 136 | #SBATCH --exclusive |
| 137 | }}}quit |
| 138 | * Commande (exemple) : |
| 139 | {{{ |
| 140 | time srun --mpi=pmi2 -m cyclic \ |
| 141 | --cpu_bind=map_cpu:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23\ |
| 142 | --multi-prog ./ztask_file.conf |
| 143 | }}} |
| 144 | * avec ./ztask_file.conf contenant, oasis en premier obligatoirement: |
| 145 | {{{ |
| 146 | 0-295 ./xios_server.exe |
| 147 | 296-13295 ./opa |
| 148 | }}} |
| 149 | * Résultat : srun lance 13296 processus : 13000 pour NEMO et 296 pour XIOS |
| 150 | |
| 151 | == Couplage IPSL : LMDZ + NEMO + 1 XIOS en mode serveur == |
| 152 | |
| 153 | * ajouter dans le .bashrc ou au début du script slurm |
| 154 | {{{ |
| 155 | ulimit -S -s unlimited # stack |
| 156 | ulimit -S -d unlimited # data area |
| 157 | ulimit -S -m unlimited # memory |
| 158 | ulimit -S -c 20 |
| 159 | ulimit -S -n unlimited # memory |
| 160 | ulimit -S -q unlimited # memory |
| 161 | }}} |
| 162 | * script automatique de création du rankfile : create_rankfile_cyclic_nemo_16ppn.sh (notation logique avec BullxMPI sur noeuds HT) |
| 163 | {{{ |
| 164 | MPI_LMDZ=$1 |
| 165 | OMP_LMDZ=$2 |
| 166 | PPN_LMDZ=$3 |
| 167 | MPI_NEMO=$4 |
| 168 | PPN_NEMO=$5 |
| 169 | MPI_XIOS=$6 |
| 170 | PPN_XIOS=$7 |
| 171 | |
| 172 | # ........................................................... |
| 173 | |
| 174 | for i in $( nodeset -e $SLURM_NODELIST) ; do |
| 175 | echo $i >> atos_host |
| 176 | for j in {1..24}; do |
| 177 | echo $i >> atos_host1 |
| 178 | done |
| 179 | done |
| 180 | |
| 181 | rm -rf atos_lmdz_rankfile atos_xios_rankfile atos_nemo_rankfile |
| 182 | |
| 183 | compt=1 # rang absolu |
| 184 | go_nemo=0 |
| 185 | go_xios=0 |
| 186 | |
| 187 | for node in $( nodeset -e $SLURM_NODELIST ) ; do boucle sur les noeuds présents dans la liste fournie par SLURM |
| 188 | compt1=1 # rang local pour LMDZ |
| 189 | FIRST_CORE=0 |
| 190 | FIRST_CORE1=0 |
| 191 | while [[ $compt -le $MPI_LMDZ && $compt1 -le $PPN_LMDZ ]]; do |
| 192 | |
| 193 | if [ $compt1 -le $(( $PPN_LMDZ / 2 )) ] ; then |
| 194 | |
| 195 | SOC=0 # scoket 0 |
| 196 | |
| 197 | LAST_CORE=$(( $FIRST_CORE + ( $OMP_LMDZ * 2) )) |
| 198 | STRING="" |
| 199 | |
| 200 | for core in ` seq $FIRST_CORE 2 $(( $LAST_CORE - 2 )) `; do |
| 201 | if [ $core == $FIRST_CORE ]; then |
| 202 | STRING=$( echo $core ) |
| 203 | else |
| 204 | STRING=$( echo $STRING','$core ) |
| 205 | fi |
| 206 | done |
| 207 | FIRST_CORE=$LAST_CORE |
| 208 | |
| 209 | else # socket 1 |
| 210 | |
| 211 | SOC=1 |
| 212 | LAST_CORE=$(( $FIRST_CORE1 + ( $OMP_LMDZ * 2) )) |
| 213 | STRING="" |
| 214 | |
| 215 | for core in `seq $FIRST_CORE1 2 $(( $LAST_CORE - 2 )) `; do |
| 216 | if [ $core == $FIRST_CORE1 ]; then |
| 217 | STRING=$( echo $core ) |
| 218 | else |
| 219 | STRING=$( echo $STRING','$core ) |
| 220 | fi |
| 221 | done |
| 222 | FIRST_CORE1=$LAST_CORE |
| 223 | fi |
| 224 | |
| 225 | echo "rank "$(( $compt - 1 ))"="$node" slot="$SOC":"$STRING >> atos_lmdz_rankfile |
| 226 | |
| 227 | compt=$(( $compt + 1 )) # maj rang absolu |
| 228 | compt1=$(( $compt1 + 1 )) # maj rang local LMDZ |
| 229 | |
| 230 | old_node=$node # dernier noeud occupé par LMDZ |
| 231 | |
| 232 | done # end while for lmdz #------------------------------------------------------------ |
| 233 | # |
| 234 | # NEMO ne coexiste pas sur le même noeud que des tâches LMDZ |
| 235 | # NEMO : creation d'uh fichier temporaire NODEFILE pour NEMO |
| 236 | # |
| 237 | if [[ $compt -eq $(( $MPI_LMDZ + 1 )) && $old_node != $node ]]; then |
| 238 | go_nemo=1 |
| 239 | fi |
| 240 | |
| 241 | if [[ $go_nemo -eq 1 && $compt -le $(( $MPI_LMDZ + $MPI_NEMO )) ]]; then |
| 242 | |
| 243 | compt2=1 # rang local NEMO |
| 244 | while [[ $compt2 -le $PPN_NEMO && $compt -le $(( $MPI_LMDZ + $MPI_NEMO )) ]]; do |
| 245 | |
| 246 | STRING=$(( ( $compt2 - 1 ) * 2 )) |
| 247 | |
| 248 | |
| 249 | echo "rank "$(( $compt - 1 ))"="$node" slot="$STRING >> atos_nemo_rankfile |
| 250 | compt=$(( $compt + 1 )) # rang absolu |
| 251 | compt2=$(( $compt2 + 1 )) # rang local NEMO |
| 252 | done |
| 253 | fi |
| 254 | # |
| 255 | # XIOS |
| 256 | # |
| 257 | if [[ $compt -eq $(( $MPI_LMDZ + $MPI_NEMO + 1 )) ]]; then |
| 258 | go_xios=1 |
| 259 | fi |
| 260 | |
| 261 | while [[ $go_xios -eq 1 && $compt -le $(( $MPI_LMDZ + $MPI_NEMO + $MPI_XIOS )) ]]; do |
| 262 | STRING=$(( ( $compt2 + 1 ) * 2 )) |
| 263 | echo "rank "$(( $compt - 1 ))"="$node" slot="$STRING >> atos_xios_rankfile |
| 264 | compt=$(( $compt + 1 )) |
| 265 | compt2=$(( $compt2 + 1 )) |
| 266 | done |
| 267 | done # boucle for sur les noeuds présents dans la liste de SLURM |
| 268 | # ------------------------------------------------------------------------------------------- |
| 269 | # ------------------------------------------------------------------------------------------ |
| 270 | # NEMO : travail spécifique sur la distribution cyclique |
| 271 | # Cyclic for NEMO |
| 272 | # |
| 273 | First_rank_nemo=$(( $MPI_LMDZ + 1 )) |
| 274 | compt=1 # rang NEMO |
| 275 | while [[ $compt -le $MPI_NEMO ]]; do # boucle locale sur les rangs NEMO |
| 276 | |
| 277 | compt2=1 # nombre de rangs NEMO sur le noeud en cours ( pour dépeuplement) |
| 278 | compt_core=$compt2 # initialisation compteur position du core utilisé sur le socketen suivant la numérotation logique |
| 279 | max_on_socket=$(( $PPN_NEMO /2 )) |
| 280 | while [[ $compt2 -le $PPN_NEMO && $compt -le $MPI_NEMO ]]; do # parcours des rangs NEMO |
| 281 | |
| 282 | for i in $( cat atos_nemo_rankfile | sed 's@=@ @g' | awk '{print $3}' | sort | uniq ) ; do # parcours de tous les noeuds pour NEMO |
| 283 | |
| 284 | if [ $compt -le $MPI_NEMO ] ; then |
| 285 | echo "rank "$(( $First_rank_nemo + $compt - 2 ))"="$i" slot="$(( 2 * ( $compt_core - 1 ) )) >> atos_nemo_rankfile1 |
| 286 | last_compt=$(( $First_rank_nemo + $compt - 2 )) # compteur rang nemo |
| 287 | old_node1=$i |
| 288 | old_string=$(( $compt_core - 1 )) |
| 289 | compt=$(( $compt + 1 )) # rang NEMO |
| 290 | fi |
| 291 | |
| 292 | done # fin parcours sur les noeuds du fichier temporaire NODEFILE pour NEMO |
| 293 | compt2=$(( $compt2 + 1 )) # rang local NEMO |
| 294 | |
| 295 | # depeuplement 8 NEMO par socket et 16 par noeud |
| 296 | # Quand commence -t on au deuxième socket ? |
| 297 | ### if [ $compt2 -eq 9 ]; then # 8 rangs NEMO non consecutifs sont déjà placés |
| 298 | if [ $compt2 -eq $(( $max_on_socket + 1 )) ]; then # premier socket a atteint la limite max_on_socket |
| 299 | compt_core=13 # on passe au deuxieme socket (numerotation logigue pour OpenMPI et pour le deuxieme socket sur Occigen cela commence au slot=24 == 2*(13-1) |
| 300 | else |
| 301 | compt_core=$(( $compt_core + 1 )) |
| 302 | fi |
| 303 | done |
| 304 | done |
| 305 | mv atos_nemo_rankfile1 atos_nemo_rankfile |
| 306 | |
| 307 | ######## XIOS with cyclic nemo |
| 308 | |
| 309 | if [ $MPI_XIOS = 1 ]; then |
| 310 | |
| 311 | echo "rank "$(( $last_compt + 1 ))"="$old_node1" slot="$(( ( $old_string + 1 ) * 2 )) > atos_xios_rankfile |
| 312 | |
| 313 | fi |
| 314 | |
| 315 | |
| 316 | ######## |
| 317 | |
| 318 | rm -f atos_rankfile |
| 319 | |
| 320 | cat atos_lmdz_rankfile >> atos_rankfile |
| 321 | cat atos_nemo_rankfile >> atos_rankfile |
| 322 | cat atos_xios_rankfile >> atos_rankfile |
| 323 | |
| 324 | }}} |
| 325 | * script SLURM sur OCCIGEN |
| 326 | {{{ |
| 327 | #!/bin/bash |
| 328 | #SBATCH --nodes=26 |
| 329 | #SBATCH --ntasks=269 |
| 330 | #SBATCH --time=00:30:00 |
| 331 | #SBATCH -J IPSL |
| 332 | ##SBATCH -o IPSL_occigen.o.%J |
| 333 | ##SBATCH -e IPSL_occigen.e.%J |
| 334 | #SBATCH --mem=120GB |
| 335 | #SBATCH --cpu_bind=none |
| 336 | #SBATCH --exclusive |
| 337 | |
| 338 | module load intel/15.0.3.187 |
| 339 | module load bullxmpi/1.2.8.4-mxm |
| 340 | |
| 341 | module load hdf5/1.8.14_parallel_bullxmpi |
| 342 | module load netcdf/bullxmpi/4.3.3-rc2 |
| 343 | module load netcdf/bullxmpi/fortran-4.4.1_4.3.3-rc2 |
| 344 | module load ferret/6.93 |
| 345 | |
| 346 | MPI_LMDZ=47 # nombre de tâches LMDZ |
| 347 | PPN_LMDZ=4 # nombre de tâches LMDZ par noeud de 24 cores |
| 348 | OMP_LMDZ=$(( 24 / $PPN_LMDZ )) # nombre de threads par tâche MPI LMDZ |
| 349 | MPI_NEMO=221 # nombre de tâches NEMO |
| 350 | |
| 351 | export OMP_NUM_THREADS=$OMP_LMDZ |
| 352 | #export KMP_STACKSIZE=2g |
| 353 | export KMP_STACKSIZE=3g |
| 354 | |
| 355 | * tuning pour bullxmpi |
| 356 | |
| 357 | export KMP_BLOCKTIME=infinite |
| 358 | export OMP_NESTED=FALSE |
| 359 | export MXM_MEM_ON_DEMAND_MAP=n |
| 360 | export OMPI_MCA_mpi_leave_pinned=0 |
| 361 | |
| 362 | export bin_dir=$HOME/bin-with-xCORE-AVX2 |
| 363 | cp $bin_dir/* . |
| 364 | |
| 365 | # recopie des scripts |
| 366 | cp ../scripts/s*ksh . |
| 367 | # recopie des donnees d entree |
| 368 | ln -sf ../INPUT_CURIE/* . |
| 369 | # les arguments passes au script de creation automatique du rankfile sont : |
| 370 | # nb de tâches LMDZ - nb de threads/tâche - nombre de tâches LMDZ/noeud - nombre de tâches NEMO - nombre de tâches NEMO par noeud - nombre de tâches XIOS - nombre de tâches XIOS par noeud |
| 371 | bash $SLURM_SUBMIT_DIR/create_rankfile_cyclic_nemo_16ppn.sh $MPI_LMDZ $OMP_LMDZ $PPN_LMDZ $MPI_NEMO 16 1 1 |
| 372 | |
| 373 | # ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 374 | echo "RUN STARTS" |
| 375 | date |
| 376 | # |
| 377 | # recopie du script slurm en cours dans le repertoire de travail sur $SCRATCHDIR |
| 378 | cp $0 . |
| 379 | # |
| 380 | # execution |
| 381 | # |
| 382 | /usr/bin/time mpirun --rankfile atos_rankfile -np $MPI_LMDZ ./script_lmdz.ksh : -np $MPI_NEMO ./script_opa.ksh : -np 1 ./script_xios.ksh |
| 383 | # |
| 384 | ##################################################################################################################################################### |
| 385 | * scripts ksh de lancement des trois codes gmc.e opa et xios_serve.exe |
| 386 | {{{ |
| 387 | cat script_lmdz.ksh |
| 388 | #!/bin/ksh |
| 389 | export KMP_STACKSIZE=3g |
| 390 | ./gcm.e |
| 391 | }}} |
| 392 | {{{ |
| 393 | cat script_opa.ksh |
| 394 | #!/bin/ksh |
| 395 | ./opa |
| 396 | }}} |
| 397 | {{{ |
| 398 | cat script_xios.ksh |
| 399 | #!/bin/ksh |
| 400 | ./xios_server.exe |
| 401 | }}} |
| 402 | |
| 403 | |
| 404 | |
| 405 | |