Strumenti Utente

Strumenti Sito


grid:mpi-report-it

English page

MPI jobs su INFN GRID - Obbiettivo

Ci proponiamo di fornire le conoscenze di base per l'installazione e l'uso di MPI su INFNGrid a seguito dell' update 14 di gLite che recepisce le indicazioni dell'MPI Working Group di Egee

Ambiente usato per i test:


Principali novita':

mpi-start

Questo tool, sviluppato all' HLRS di Stoccarda, e' un insieme di script, organizzati in 3 Framework, che consente di gestire la configurazione specifica di un sito MPI.

  • Scheduler Framework: Consente di estrarre automaticamente dallo scheduler (SGE, PBS o LSF) il Machinefile.
  • MPI Framework: Gestisce la catena generica di esecuzione pre_run_hook/mpi_exec/post_run_hook in cui l'utente puo' indicare il flavour di MPI da utilizzare. Sono supportati OpenMPI, Mpich, Mpich2 e Lam-MPI.
  • File distribution Framework: Se la Working directory non e' condivisa gestisce la distribuzione dei file utilizzando SSH o mpi_mt

L'utente eseguira' uno script che definisce alcune opportune varibili di ambiente e mette in esecuzione mpi-start. Ecco un esempio semplificato di script:

export I2G_MPI_APPLICATION=test-mpi
export I2G_MPI_APPLICATION_ARGS=
export I2G_MPI_TYPE=openmpi
export I2G_MPI_PRE_RUN_HOOK=mpi-hooks.sh
export I2G_MPI_POST_RUN_HOOK=mpi-hooks.sh
# Invoke mpi-start:
$I2G_MPI_START
mpirun "dummy" (non più richiesto dal recente update del middleware: GliteWMS 3.1.12)

Una ulteriore modifica nel middleware di Egee e' necessaria poiche' se nel JDL specifichiamo:

JobType=MPICH
Executable=mio-prog
..

in questo esempio mio-prog e' inteso come l'eseguibile mpi compilato con mpich e come tale viene messo in esecuzione (mpirun mio-prog) sui worker nodes selezionati dallo scheduler. Per poter eseguire lo script di lancio di mpi-start e' necessario un workaround che consiste nell'installazione (da parte di Yaim) di un opportuno script mpirun “dummy”.

Installazione

In questa sezione si vuole illustrare il procedimenti di installazione e configurazione delle utility del middleware e di mpi. Tutte le operazioni elencate sono da eseguire su tutti i Worker Node.

Si suppone che sui WN sia già correttamente installato e configurato il middleware gLite versione 3.1 update 14/15/16 o superiore. Qui verranno solo discusse ed esposte le modifiche a tale configurazione.

Installare mpi

Se non è già presente installare il MetaPackage glite-MPI_utils che comprende i pacchetti glite-yaim-mpi, i2g-mpi-start, mpich e mpiexec:

yum install glite-MPI_utils

La successiva configurazione del Node Type mpi_wn andrà a creare lo script /opt/glite/bin/mpirun che verra' eseguito in sostituzione del mpirun originale, con il compito di passare gli argomenti in esecuzione.

Il pacchetto mpich (attualmente la relaease 1.2.7) viene installato con Prefix /opt/mpich-1.2.7p1/bin/

Il pacchetto openmpi incluso nella distribuzione SL4x (attuamente 1.3) non e' utilizzabile senza modifiche all'environment di default, poichè l'installazione avviene con Prefix /usr/bin e risulterebbe quindi precedere nella PATH l'mpirun “dummy” installato da Yaim. Volendo utilizzare openmpi e' necessario modificare il prefisso di installazione, in quanto lo script dummy /opt/glite/bin/mpirun deve precedere nella PATH gli altri mpirun presenti nel sistema. Si può anche modificare la PATH di default creando un file /etc/profile.d/ facendo in modo che /opt/glite/bin preceda /usr/bin, ma questo metodo non è stato testato. Dopo il recente update di GliteWMS questo non è più necessario.

Se si usa SL4x si può scaricare un rpm già compilato di openmpi con /opt come prefix di installazione (binari installati in /opt/openmpi/<version>/bin/). Le impostazioni di compilazione sono quelle di default impostate dal team di openmpi.

Nel caso si desideri ricompilare scaricare l'rpm sorgente dal sito di openmpi installarlo e ricompilare con

rpmbuild -bb --define 'mflags -jN' --define 'build_all_in_one_rpm 1' --define 'install_in_opt 1' --define 'cflags -g' --target <PLATFORM> /usr/src/redhat/SPECS/openmpi-1.3.spec

dove N è il numero di cpu più una disponibili sulla macchina, il team di openmpi di default passa 4 (se N - 1 è maggiore del numero delle CPU non si incontreranno errori, è semplicemente superfluo) e <PLATFORM> è l'architettura usata dalle macchine.

Attenzione: Sul nodo in cui avviene la ricompilazione è necessario che il pacchetto torque-devel sia installato per il avere il supporto per l'autodiscovery del machinefile e del numero di processori. Tale pacchetto non è presente nei repo ufficiali.

Configurare Yaim

E' necessario aggiungere le opportune direttive in site-info.def o nei file di configurazione dedicati a mpi glite-mpi, glite-mpi_ce, glite-mpi_wn come indicato nei file di esempio in /opt/glite/yaim/examples/siteinfo/services/; è consigliabile leggere sempre questi file dato che sono aggiornati.

Ad esempio se si desidera una installazione di openmpi 1.2.6 e mpich 1.2.7 con shared-home la configurazione necessaria e' la seguente:

glite-mpi

Qui ci sono le configurazioni generiche di mpi

############################################
# Mandatory parameters in services/mpi     #
############################################

# N.B. this file contains common configuration for CE and WN
# As such, it should be included in your site-info.def to ensure
# that the configuration of the CE and WNs remains in sync.

#----------------------------------
# MPI-related configuration:
#----------------------------------
# Several MPI implementations (or "flavours") are available.
# If you do NOT want a flavour to be configured, set its variable
# to "no". Otherwise, set it to "yes". If you want to use an
# already installed version of an implementation, set its "_PATH" and
# "_VERSION" variables to match your setup (examples below).
#
# NOTE 1: the CE_RUNTIMEENV will be automatically updated in the file
# functions/config_mpi_ce, so that the CE advertises the MPI implementations
# you choose here - you do NOT have to change it manually in this file.
# It will become something like this:
#
#   CE_RUNTIMEENV="$CE_RUNTIMEENV
#              MPICH
#              MPICH-1.2.7p4
#              MPICH2
#              MPICH2-1.0.4
#              OPENMPI
#              OPENMPI-1.1
#              LAM"
#
# NOTE 2: it is currently NOT possible to configure multiple concurrent
# versions of the same implementations (e.g. MPICH-1.2.3 and MPICH-1.2.7)
# using YAIM. Customize "/opt/glite/yaim/functions/config_mpi_ce" file
# to do so.

MPI_MPICH_ENABLE=${MPI_MPICH_ENABLE:-"yes"}
MPI_MPICH2_ENABLE=${MPI_MPICH2_ENABLE:-"no"}
MPI_OPENMPI_ENABLE=${MPI_OPENMPI_ENABLE:-"yes"}
MPI_LAM_ENABLE=${MPI_LAM_ENABLE:-"no"}

#---
# Example for using an already installed version of MPI.
# Just fill in the path to its current installation (e.g. "/usr")
# and which version it is (e.g. "6.5.9").
#---
MPI_MPICH_PATH=${MPI_MPICH_PATH:-"/opt/mpich-1.2.7p1/"}
MPI_MPICH_VERSION=${MPI_MPICH_VERSION:-"1.2.7p1"}
MPI_OPENMPI_PATH="/opt/openmpi/1.2.6/"
MPI_OPENMPI_VERSION="1.2.6"
#MPI_MPICH2_PATH="/opt/mpich2-1.0.4/"
#MPI_MPICH2_VERSION=${MPI_MPICH2_VERSION:-"1.0.4"}
#MPI_OPENMPI_VERSION="1.1"
#MPI_LAM_VERSION="7.1.2"

# If you do NOT provide a shared home, set MPI_SHARED_HOME to "no" (default).
#MPI_SHARED_HOME=${MPI_SHARED_HOME:-"no"}

# If you do provide a shared home and Grid jobs normally start in that area,
# set MPI_SHARED_HOME to "yes".
MPI_SHARED_HOME="yes"

# If you have a shared area but Grid jobs don't start there, then set
# MPI_SHARED_HOME to the location of this shared area. The permissions
# of this area need to be the same as /tmp (i.e. 1777) so that users
# can create their own subdirectories.
#MPI_SHARED_HOME=/share/cluster/mpi


#
# If you do NOT have SSH Hostbased Authentication between your WNs,
# set this variable to "no" (default). Otherwise set it to "yes".
#
#MPI_SSH_HOST_BASED_AUTH=${MPI_SSH_HOST_BASED_AUTH:-"no"}
MPI_SSH_HOST_BASED_AUTH="yes"

#
# If you provide mpiexec (http://www.osc.edu/~pw/mpiexec/index.php)
# for MPICH or MPICH2, please state the full path to that file here.
# Otherwise do not set this variable. (Default is to set this to
# the location of mpiexec set by the glite-MPI_WN metapackage.
MPI_MPICH_MPIEXEC=${MPI_MPICH_MPIEXEC:-"/opt/mpiexec-0.82/bin/mpiexec"}
MPI_OPENMPI_MPIEXEC="/opt/openmpi/1.2.6/bin/mpiexec"

glite-mpi_ce

Qui ci sono le configurazioni di mpi per il CE

# N.B. this file contains MPI configuration specific to the CE.
# For other important MPI variables shared between the CE and
# WNs please see glite-mpi.

# The MPI CE config function can create a submit filter for
# Torque to ensure that CPU allocation is performed correctly.
# Change this variable to "yes" to have YAIM create this filter.
# Warning: if you have an existing torque.cfg it will be modified.
MPI_SUBMIT_FILTER=${MPI_SUBMIT_FILTER:-"no"}

glite-mpi_wn

Qui ci sono le configurazioni di mpi per i WN

# N.B. this file contains MPI configuration specific to WNs.
# For other important MPI variables shared between the CE and
# WNs please see glite-mpi in the YAIM examples directory.

#---
# Example for using an already installed version of MPI.
# Just fill in the path to its current installation (e.g. "/usr").
# The version (e.g. "6.5.9") should be set in site-info.def as
# it is needed both on CE and WNs.

#---
MPI_MPICH_PATH="/opt/mpich-1.2.7p1/"
#MPI_MPICH2_PATH="/opt/mpich2-1.0.4/"
MPI_OPENMPI_PATH="/opt/openmpi/1.2.6/"

# If you provide mpiexec (http://www.osc.edu/~pw/mpiexec/index.php)
# for MPICH or MPICH2, please state the full path to that file here.
# Otherwise do not set this variable. (Default is to set this to
# the location of mpiexec set by the glite-MPI_WN metapackage.
MPI_MPICH_MPIEXEC="/opt/mpiexec-0.82/bin/mpiexec"
#MPI_MPICH2_MPIEXEC="/opt/mpiexec-0.82/bin/mpiexec"
MPI_OPENMPI_MPIEXEC="/opt/openmpi/1.2.6/bin/mpiexec"

# If you have installed i2g-mpi-start in a non-standard location
# please set this variable to its path.
# MPI_MPI_START="/my/root/i2g/bin/mpi-start"

Configurazione alternativa

Se si preferisce si può mettere tutto nel file di configurazione site-info.def, ma è sconsigliato dato che nella guida ufficiale si usa la configurazione precedente.

MPI_OPENMPI_ENABLE=${MPI_OPENMPI_ENABLE:-"yes"}
MPI_OPENMPI_PATH="/opt/openmpi/1.2.6/" 
MPI_OPENMPI_VERSION="1.2.6" 
MPI_OPENMPI_MPIEXEC="/opt/openmpi/1.2.6/bin/mpiexec"

MPI_MPICH_ENABLE=${MPI_MPICH_ENABLE:-"yes"}
MPI_MPICH_PATH="/opt/mpich-1.2.7p1/" 
MPI_MPICH_VERSION="1.2.7" 
MPI_MPICH_MPIEXEC="/opt/mpiexec-0.82/bin/mpiexec" 

# se la home è condivisa dai WN per esempio con nfs (vivamente consigliato)
MPI_SHARED_HOME="yes" 
# se è abilitata l'autenticazione ssh sui WN (ovviamente deve avvenire tramite chiave  rsa e senza password)
MPI_SSH_HOST_BASED_AUTH="yes" 

# se i WN e il CE hanno la cartella /home condivisa questa variabile va settata (nel nostro esempio usiamo pbs)
JOB_MANAGER=pbs 

#Aggiungere alla variabile CE_RUNTIMEENV le seguenti Tag, mpi-start è installato dal pacchetto glite-MPI_utils
OPENMPI
OPENMPI-1.2.6
MPI-START
MPI_SHARED_HOME

Se si desidera usare più di una implementazione/versione di mpi si devono definire le corrispondenti variabili di configurazione (ovvero MPI_<secondo-flavour>_ENABLE… ecc…)

Invocare Yaim

/opt/glite/yaim/bin/ig_yaim -c -s my-site-info.def -n ig_WN_torque_noafs -n MPI_WN

Questo comando genera, tra le altre cose, lo script dummy /opt/glite/bin/mpirun
E' quindi fondamentale che nella variabile d'ambiente PATH /opt/glite/bin preceda le path delle varie implementazioni/versioni di mpi.

Collegamenti esterni

Utilizzo

Script Wrapper per mpi-start

Lo script definisce le variabili d'ambiente, necessarie a mpi-start, per il flavor scelto. Definisce inoltre gli script hook scelti. In ultimo lo script lancia mpi-start.

mpi-start-wrapper

#!/bin/bash

# Pull in the arguments.
MY_EXECUTABLE=`pwd`/$1
MPI_FLAVOR=$2

# Convert flavor to lowercase for passing to mpi-start.
MPI_FLAVOR_LOWER=`echo $MPI_FLAVOR | tr '[:upper:]' '[:lower:]'`

# Pull out the correct paths for the requested flavor.
eval MPI_PATH=`printenv MPI_${MPI_FLAVOR}_PATH`

# Ensure the prefix is correctly set.  Don't rely on the defaults.
eval I2G_${MPI_FLAVOR}_PREFIX=$MPI_PATH
export I2G_${MPI_FLAVOR}_PREFIX

# Touch the executable.  It exist must for the shared file system check.
# If it does not, then mpi-start may try to distribute the executable
# when it shouldn't.
touch $MY_EXECUTABLE

# Setup for mpi-start.
export I2G_MPI_APPLICATION=$MY_EXECUTABLE
export I2G_MPI_APPLICATION_ARGS=
export I2G_MPI_TYPE=$MPI_FLAVOR_LOWER
export I2G_MPI_PRE_RUN_HOOK=mpi-hooks.sh
export I2G_MPI_POST_RUN_HOOK=mpi-hooks.sh

# If these are set then you will get more debugging information.
export I2G_MPI_START_VERBOSE=1
#export I2G_MPI_START_DEBUG=1

# Invoke mpi-start.
$I2G_MPI_START

Lo script è molto generale ed è modificabile per le specifiche esigenze dell'utente. Per esempio se si vuole utilizzare questo script su un cluster in cui non è presente mpi-start basta aggiungere all'inizio del precedente script

if [ "x$I2G_MPI_START" = "x" ]; then
    # untar mpi-start and set up variables
    tar xzf mpi-start-*.tar.gz
    export I2G_MPI_START=bin/mpi-start
    MPIRUN=`which mpirun`
    export MPI_MPICH_PATH=`dirname $MPIRUN`
fi

Hooks per mpi-start

Ecco un esempio di script hook. Questo script serve per fare operazioni di pre e post run, per esempio compilare il programma mpi o copiare i risultati su uno storage element, ed è essenziale che sia un file separato dal precedente script wrapper

mpi-hooks

#!/bin/sh

# This function will be called before the MPI executable is started.
# You can, for example, compile the executable itself.
#
pre_run_hook () {

  # Compile the program.
  echo "Compiling ${I2G_MPI_APPLICATION}"

  # Actually compile the program.
  cmd="mpicc ${MPI_MPICC_OPTS} -o ${I2G_MPI_APPLICATION} ${I2G_MPI_APPLICATION}.c"
  echo $cmd
  $cmd
  if [ ! $? -eq 0 ]; then
    echo "Error compiling program.  Exiting..."
    exit 1
  fi

  # Everything's OK.
  echo "Successfully compiled ${I2G_MPI_APPLICATION}"

  return 0
}

# This function will be called before the MPI executable is finished.
# A typical case for this is to upload the results to a storage element.
post_run_hook () {
  echo "Executing post hook."
  echo "Finished the post hook."

  return 0
}

Si devono definire le due funzioni pre_run_hook e post_run_hook, anche in file diversi, che verranno chiamate da mpi-start.

Creare il Job Description Language

Il JobYype deve essere MPICH anche se il flavor scelto è differente.
La variabile Arguments deve contenere prima il nome del programma e poi il flavour di mpi.
Nell'hook di esempio il nome del file sorgente coincide con il nome del file .c.

mpitest.jdl

JobType = "Normal";
#prima dell'update di GliteWMS serviva JobType = "MPICH";
NodeNumber = 8;
Executable = "mpi-start-wrapper.sh";
Arguments = "mpi-test OPENMPI";
StdOutput = "mpi-test.out";
StdError = "mpi-test.err";
InputSandbox = {"mpi-start-wrapper.sh","mpi-hooks.sh","mpi-test.c"};
OutputSandbox = {"mpi-test.err","mpi-test.out"};
Requirements =
  Member("MPI-START", other.GlueHostApplicationSoftwareRunTimeEnvironment)
  && Member("OPENMPI", other.GlueHostApplicationSoftwareRunTimeEnvironment)
  ;

Collegamenti esterni

Esecuzione in locale

Mpi-start può essere facilmente utilizzato anche per l'esecuzione tramite code in locale, per esempio tramite torque, è sufficiente fare qualche minima modifica allo script usato in precedenza

mpi-start-wrapper-torque

#!/bin/bash
#
# Pull in the arguments.
#//// Customized for local execution /////
WORK_DIR=$WD
MY_EXECUTABLE=$WORK_DIR/$EXE
MPI_FLAVOR=$FLAVOR
#/////////////////////////////////////////

# Convert flavor to lowercase in order to pass it to mpi-start.
MPI_FLAVOR_LOWER=`echo $MPI_FLAVOR | tr '[:upper:]' '[:lower:]'`

# Pull out the correct paths for the requested flavor.
eval MPI_PATH=`printenv MPI_${MPI_FLAVOR}_PATH`

# Ensure the prefix is correctly set.  Don't rely on the defaults.
eval I2G_${MPI_FLAVOR}_PREFIX=$MPI_PATH
export I2G_${MPI_FLAVOR}_PREFIX

# Touch the executable.  It must exist for the shared file system check.
# If it does not, then mpi-start may try to distribute the executable
# (while it shouldn't do that).
touch $MY_EXECUTABLE

# Setup for mpi-start.
export I2G_MPI_APPLICATION=$MY_EXECUTABLE
export I2G_MPI_APPLICATION_ARGS=
export I2G_MPI_TYPE=$MPI_FLAVOR_LOWER

#//// Customized for local execution /////
export I2G_MPI_PRE_RUN_HOOK=$WORK_DIR/mpi-hooks.sh
export I2G_MPI_POST_RUN_HOOK=$WORK_DIR/mpi-hooks.sh
#////////////////////////////////////////

# If these are set then you will get more debugging information.
export I2G_MPI_START_VERBOSE=1
#export I2G_MPI_START_DEBUG=1

# Invoke mpi-start.
$I2G_MPI_START

e si esegue lanciando il comando

qsub -l nodes=4 -q albert -v EXE=cpi_mpi,FLAVOR=OPENMPI,WD=$PWD mpi-start-wrapper-torque.sh

Siccome non si possono passare argomenti allo script wrapper tramite torque, dobbiamo esportare variabili d'ambiente tramite l'opzione -v per poter avere uno script generale. Inoltre è necessario indicare tra le variabili esportare la current working directory, questo perché non essendo più eseguito da remoto, ma in locale i file coinvolti potrebbero essere in un qualunque punto dell'intera architettura delle directory invece che nella home di globus come accade quando si esegue in remoto tramite glite. Nel caso la variabile PWD non sia disponibile nel sistema si può usare

`pwd`

al suo posto, o la si può anche indicare manualmente.

La stessa procedura funziona perfettamente anche con mpich, ma bisogna ricordarsi di modificare gli argomenti di compilazione in quanto mpich non esegue automaticamente -lm mentre openmpi si.

Troubleshooting

mpi-start

La versione di deployment di mpi-start fornita nei repositories di INFNGrid è attualmente i2g-mpi-start-0.0.52-1 che presenta un malfunzionamento in openmpi: c'e un errore nel file /opt/i2g/etc/mpi-start/openmpi.mpi (MPI_SPECIFIC_PARAMS+=“..”)

Volendo utilizzare openmpi e' quindi necessario installare una versione piu' aggiornata di mpi-start, ad esempio con il comando:

rpm -Uvh http://quattor.web.lal.in2p3.fr/packages/glite-3.1/unofficial/i2g-mpi-start-0.0.58-1.noarch.rpm

Inoltre con tale versione il supporto a LSF e mpiexec è incompleto e in molti casi non funziona.

Purtroppo sia mpi-start-0.0.58 che mpi-start-0.0.52 ha problemi con mpiexec in presenza di LSF come gestore delle code, sia nella distribuzione dei file su home non sharate, sia sull'esecuzione del job stesso, siccome mpiexec viene chiamato anche se non c'è alcun ambiente PBS in uso.

Patch per mpi-start-0.0.58

Abbiamo sviluppato una patch per risolvere questo problema e altre cose minori. Per applicare questa patch bisogna essere nella directory superiore a quella dove è contenuto il file eseguibile mpi-start, cioè quella che dovrebbe contenere le cartelle bin e etc. Di default questa directory è /opt/i2g/mpi-start. In questa directory è sufficiente lanciare patch -p0.

cd $(dirname $I2G_MPI_START)/.. && wget http://www.fis.unipr.it/grid/wiki_files/mpi-start-0.0.58-fix.patch && patch -p0 < mpi-start-0.0.58-fix.patch

Questa patch è stata accettata dagli sviluppatori di mpi-start e sarà aggiunta nella versione 0.0.60.




Roberto Alfieri - Enrico Tagliavini — 2009/05/18

/var/www/html/dokuwiki/data/pages/grid/mpi-report-it.txt · Ultima modifica: Y/m/d H:i da