HOME| CRESCO| Guide/tutorials| Contatti| F.A.Q.

Guide / tutorials

Compilatori/Compilazione



SOMMARIO:

  1. Compilatori installati su CRESCO
  2. Comandi per la compilazione Seriale
  3. Compilazione di un'applicazione parallela (MPI, OpenMP)
    1. Implementazioni (librerie) MPI disponibili
    2. Selezione libreria MPI e compilatori:
      1. Selezione dell'ambiente parallelo tremite l'uso del software Modules
    3. Comandi per la compilazione MPI/OpenMP
    4. Esecuzione interattiva di un programma MPI
  4. Compilazione a 32 bit su architettura x86_64
  5. Links utili

1. Compilatori installati su CRESCO

Dal 2016 le sezioni 1 e 2 dei cluster CRESCO sono dismesse; le informazioni seguenti fanno riferimento a queste sezioni ma hanno anche un carattere di validita' piu' generale e quindi una certa utilita' per coloro che non hanno esperienza di compilazione su sistemi HPC Linux.
I compilatori installati sulla Sez. 1 e 2, per la compilazione di codici: Fortran 77/90/95, C, C++, Java sono i seguenti:
I comandi per la compilazione sono riassunti in una tabella nella successiva sezione di questa guida (2. Comandi per la compilazione Seriale). Si noti che gli stessi compilatori vengono invocati per la compilazione di codici paralleli, ovvero che utilizzino librerie MPI e/o direttive OpenMP. Per maggiori dettagli si veda: Compilazione di un'applicazione parallela (MPI, OpenMP)

[sommario]


2. Comandi per la compilazione Seriale

Per invocare il compilatore necessario al proprio codice, è sufficiente digitare il comando appropriato, essendo l'ambiente di default dell'utente impostato in modo che la variabile "PATH" (quella variabile che contiene di tutti i percorsi nel quale il sistema ricerca il comando lanciato da shell o da script), contiene tutti i percorsi relativi ai compilatori sopra citati.
La seguente tabella riassume tali comandi, validi (per il momento) per le Sezioni 1 e 2 di CRESCO.


Tab. 1

PGI GNU Intel
Fortran 77 pgf77 f77 ifort
Fortran 90/95 pgf90/pgf95 gfortran/f95 ifort
C pgcc cc, gcc icc
C++ pgCC g++, c++ icpc

In fase di compilazione vanno specificate, spesso, i seguenti valori:

In generale il comando da eseguire sarebbe:
< COMPILER >   "Preprocessor flags"   "Compiler_Options"   "Linker_flags"   "source_file"   -o "executable_name"

Ovvero piu' esplicitamente:
pgf90   -I < include dir >   -O3 -g   -L < lib dir >   factorial.f90   -o factorial.exe
in questo caso sto usando il compilatore pgf90, passando l'opzione di ottimizzazione "-O3" e di debug "-g".

La compilazione può essere semplificata con opportuni "Makefile" e/o definendo alcune variabili d'ambiente nei propri scripts o nei Makefiles:

[sommario]


3. Compilazione di un'applicazione parallela (MPI, OpenMP)

I. Implementazioni (librerie) MPI disponibili

I cluster CRESCO offrono la possibilità di sfruttare, per i propri codici Fortran, C e C++, diversi tipi di compilatori ed implementazioni di MPI che utilizzano la rete Infiniband(IB) o la Gigabit Ethernet. Per i compilatori disponibili ed i comandi per il loro utilizzo, si veda: Comandi per la compilazione Seriale.

Per quanto riguarda le librerie MPI installate, occorre tenere presente che i comandi per la compilazione e l'esecuzione dei programmi paralleli sono identici per tutte le implementazioni: "mpirun" e/o i wrapper per la compilazione parallela, come "mpif90, mpicc", hanno lo stesso nome, per esempio, sia per "OpenMPI_gcc" che per "MVAPICH_pgi". Ovviamente quello che cambia sono le librerie MPI linkate e i compilatori usati. Le implementazioni MPI disponibili sono:

  1. LAM/MPI: è disponibile solo per i compilatori GNU.
  2. OpenMPI: disponibili gli ambienti con i compilatori GNU, PGI e INTEL. Supporta il Message Passing attraverso la rete IB (si veda ad esempio: OpenMPI FAQ).
  3. MVAPICH: disponibili gli ambienti con i compilatori GNU, PGI e INTEL. Anch'essa sfrutta la rete IB, basata su MPICH e MVICH.
  4. MVAPICH2: ha le stesse caratteristiche di MVAPICH, ma implementa la semantica di MPI-2.
  5. MPI Intel: anch'essa implementa MPI-2 ed è basata su MPICH2

[sommario]

II. Selezione libreria MPI e compilatori

La seguente tabella 2 mostra le possibili combinazioni MPI + Compilatore e la loro disponibilità viene indicata tramite una stringa che identifica la coppia (e la versione):

Tab. 2

PGI GNU Intel
OpenMPI openmpi_pgi-1.2.8 openmpi_gcc-1.2.8 openmpi_intel-1.2.8
MvaPICH mvapich_pgi-1.1.0 mvapich_gcc-1.1.0 mvapich_intel-1.1.0
MvaPICH2 mvapich2_pgi-1.2p1 mvapich2_gcc-1.2p1 mvapich2_intel-1.2p1
MPIintel Non disponibile Non disponibile impi_64-3.2.1
LAM/MPI Non disponibile lam_gcc-x86_64 Non disponibile

IMPORTANTE. E' fortemente consigliato (se non necessario in certi casi) utilizzare un unico ambiente per la compilazione ed il lancio dell'applicazione MPI. Ad esempio, potrebbe succedere che l'eseguibile compilato con la libreria OpenMPI ed i compilatori della intel sia eseguibile con l'ambiente di esecuzione OpenMPI e compilatori gnu. Ma questo è, in generale un errore che potrebbe portare a comportamenti indecifrabili della propria applicazione. Quindi assicurarsi e controllare la coerenza tra la coppia MPI + Compilatore in fase di compilazione e quella utilizzata durante il running. Si consiglia di apporre una estensione ai propri eseguibili che ricordi immediatamente come è stato compilato il codice: per esempio si potrebbe seguire la seguente convenzione. Se il mio codice Fortran si chiama Hello_MPI.f90, allora chiamerò l'eseguibile compilato con Intel che linka le librerie OpenMPI nel seguente modo: Hello_MPI.openmpi_intel.

[sommario]

• Uso del software Modules

Per selezionare le librerie MPI ed il compilatore si devono utilizzare i comandi messi a disposizione dal software Environment Modules. Sui cluster Cresco l'inizializzazione dell'ambiente per il singolo utente viene effettuata grazie al software Modules. Per i dettagli sull'implementazione, sulle scelte fatte e sull'uso del software è possibile consultare la relativa documentazione.

In particolare, per impostare in maniera opportuna l'ambiente per la compilazione e la sottomissione di job paralleli non sarà disponibile il comando mpi-selector come sui restanti cluster di ENEAGRID, ma dovranno essere utiliz zati i comandi messi a disposizione da Modules.

Per listare l'elenco delle flavour disponili si potrà utilizzare il comando: La flavour impostata di default per tutti gli utenti è: Se l'utente vuole scegliere una diversa flavour dovrà utilizzare il comando: Ad esempio se si vuole scegliere la libreria OpenMPI compilata con gcc si dovrà dare il comando: A questo punto l'ambiente risulta impostato coerentemente con la scelta della nuova flavour.

N.B. Per gli utenti che chiamano bash o ksh, affinchè Modules riesca ad impostare correttamente l'ambiente, è necessario creare nella propria HOME AFS i file .bashrc o .kshrc (oppure modificarli se giá esistenti) inserendo in testa ad essi delle opportune righe di codice.

Per il file .bashrc:

if [ -f /usr/share/Modules/init/bash ]
then
. /usr/share/Modules/init/bash
fi


Per il file .kshrc:

if [ -f /usr/share/Modules/init/ksh ]
then
. /usr/share/Modules/init/ksh
fi


[sommario]


[sommario]

III. Comandi per la compilazione parallela.

Riportiamo la sintassi per la compilazione di programmi MPI (Message Passing Interface) ed OpenMP (Open Specifications for Mulit-Processing) sulle sezioni 1 e 2 di CRESCO. I due modelli di programmazione parallela vengono rispettivamente usati per architetture a memoria distribuita e a memoria condivisa. L'architettura di CRESCO è ibrida, ovvero è formata da nodi SMP (Shared Memory Processing), interconnessi via Infiniband o Gigabit Ethernet. Il sistema offre quindi la possibilità di una programmazione "intra-nodale" di tipo OpenMP, ed "inter-nodale" di tipo MPI. I due paradigmi possono essere usati nei propri codici indipendentemente l'uno dall'altro, per poi lanciare le applicazioni usando uno dei due modelli di esecuzione, o combinandone i rispettivi vantaggi.

Come visto nella sezione Selezione libreria MPI e compilatori esistono diversi ambienti paralleli. Tuttavia si noti che, indipendentemente dalle implementazioni MPI (OpenMPI, MPICH, MVAPICH, etc), il nome del comando (in realtà sono wrapper) sia per la compilazione che per la esecuzione è identico, ciò che cambia sono i compilatori invocati e le librerie MPI linkate.

Programmi MPI

La compilazione, in questo caso è formalmente del tutto analoga a quella seriale. I nomi dei comandi vanno sostituiti nel seguente modo:

Tab. 3
Tipo di Codice Comando( wrapper )
Fortran77 mpif77
Fortran90 mpif90 (*)
C mpicc
C++ mpiCC
(*) Non disponibile per l'implementazione LAM/MPI (il wrapper 'mpif77' compila anche i codici Fortran 90/95, in quanto utilizza come compilatore f95 della GNU.

Quindi come per il caso seriale per compilare il sorgente <prova.c> :
mpicc   prova.c   -o prova.exe

Vanno poi aggiunte eventuali opzioni del compilatore, linker flags e/o preprocessor flags, come precedentemente discusso per il caso seriale. Per vedere i compilatori e le librerie invocati dai wrapper della Tab. 3, si può digitare dalla shell:
mpicc   --showme
Il sistema darà una risposta del tipo:
gcc -I/usr/include/lam -I/usr/include/lam/64 -m64 -pthread -L/usr/lib64/lam -llammpio -llamf77mpi -lmpi -llam -laio -laio -lutil -ldl

Programmi OpenMP

Se il proprio codice contiene le direttive OpenMP (Vedi OpenMP: Guida e link al suo interno), occorre specificare un appropriato switch a seconda del compilatore in uso. La sintassi da usare è del tutto simile a quella per il caso seriale ed MPI parallelo, eccetto l'aggiunta del flag per OpenMP. La seguente tabella sintetizza l'opzione corrispondente ai vari compilatori:

Tab. 4
Compilatori Opzione OpenMP( switch )
PGI -mp
GNU -fopenmp
INTEL -openmp

Per esempio, per compilare il codice <prova.c> , contenente direttive OpenMP, usando i compilatori PGI, il comando da dare è:
pgcc   -mp   prova.c -o prova.exe

Ovviamente si possono aggiungere le altre opzioni o flags come per il caso seriale. Inoltre se il codice utilizza librerie MPI, oltre a contenere le direttive OpenMP, la compilazione è analoga a quella mostrata nella precedente sezione sui programmi MPI, salvo aggiungere lo switch indicato in Tab. 4.

[sommario]

IV. Esecuzione interattiva di un programma MPI

IMPORTANTE. L'esecuzione dei programmi, sia seriali ed in particolare paralleli, non dovrebbere essere mai fatta in interattivo, ovvero lanciando il programma direttamente sugli hosts dei clusters. La politica in ambienti come Griglie Computazionali e/o cluster di calcolo è quello di gestire e distribuire le risorse tramite un apposito software che esegue in batch le applicazioni utente, e che in ENEA è LSF.

!!: tuttavia per facilitare alcune operazioni di test sui propri script, gli ambienti paralleli in particolare e per fini didattici, si è scelto di destinare alcuni host delle varie sezioni Cresco per i run interattivi. Ovviamente il tempo di esecuzione è assolutamente limitato. Gli host utilizzabili per questo scopo sono i frontend interattivi (x002)

La sezione Batch Jobs/LSF è dedicata al lancio di una applicazione in batch, tramite LSF. In questa sezione riportiamo le modalità con le quali lanciare un programma MPI e gli host di Cresco utilizzabili per i run interattivi. Affinchè quanto esposto funzioni correttamente attenersi a quanto riportato di seguito.

Step 1: Selezionare (con uno dei metodi di cui sopra) openmpi_gcc oppure mvapich_gcc.

La scelta è quasi forzata in quanto il protocollo per il lancio dei task paralleli è di solito ssh oppure rsh. Ma la politica in ENEA è quella di utilizzare una facility di LSF detta blaunch per tale lancio, ma questo può essere fatto solo sotto LSF. Al fine di eseguire in interattivo va necessariamente usato ssh, che però comporta una serie di difficoltà legate ai meccanismi di autenticazione (AFS token, file di configurazione, etc). Quindi è garantito il funzionamento solo(senza che l'utente debba agire su configurazioni nella propria Home) dell'ambiente parallelo suddetto.

Step 2: Dopo la selezione dell'implementazione MPI eseguire la compilazione come precedentemente indicato.

Step 3: creare un "hostfile".

Tale file elenca gli host sui quali mpirun lancia i task paralleli. In questo caso gli host da inserire per il lancio interattivo sono i frontend interattivi (x002)

L'hostfile puo' essere omesso se si vuole usare solo un nodo interattivo.

Step 4: lancio del comando

Non è necessario fare il login su uno degli host elencati nell'hostfile, ma eseguire i seguenti comandi da una macchina di front-end:

Per OpenMPI_gcc:

mpirun -n "N_processes" --hostfile "hostfile_name" "MPI_program_name"

Per MvaPICH_gcc:

mpirun_rsh -ssh -np "N_processes" -hostfile "hostfile_name" "MPI_program_name"

Ad esempio ho compilato il programma "Hello_MPI.c" con "OpenMPI_gcc" e chiamato l'eseguibile "Hello_MPI.openmpi_gcc":

mpicc -o Hello_MPI.openmpi_gcc Hello_MPI.c

Adesso uso l'hostfile di cui sopra chiamandolo "hostfile.interattivo" e lancio il programma su 64 processori (cores ...):

mpirun -n 64 --hostfile hostfile.interattivo ./Hello_MPI.openmpi_gcc

Step 5: passare ad LSF (guida).

[sommario]


4. Compilazione a 32 bit su architettura x86_64.

Su Cresco è possibile compilare applicazioni sia seriali che parallele (MPI) a 32 bit nonostante l'architettura e le impostazioni di sistema sono per codici a 64 bit. Le librerie matematiche e numeriche da linkare devono essere anch'esse a 32 bit. A tal proposito il sistema è stato dotato delle versioni sia a 32 che a 64 bit, per esempio le intel MKL (Blas, lapach, FFT, ecc). Le uniche librerie MPI attualmente a 32 bit, che sia state testate sono le Intel MPI. Come compilare a 32 bit?

• 32 bit per codici seriali

In generale per compilare a 32 o 64 bit è necessario specificare l'opzione al compilatore: "-m32" e "-m64" rispettivamente. Ad esempio per un codice seriale C che non usi librerie esterne:
gcc -m32 -o Fib3.32.x Fib3.c

Per verificare che il binario prodotto sia quello voluto, lanciare da linea di comando:
file Fib3.32.x

la shell darà una risposta del tipo:
Fib3.32.x: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

la stringa corretta per un binario a 32 bit è ELF 32-bit LSB executable, mentre per uno a 64 bit: ELF 64-bit LSB executable.

• 32 bit per codici paralleli MPI

Come anticipato, attualmente la compilazione e l'esecuzione a 32 bit di un codice MPI può essere fatto solo usando la libreria Intel MPI. Selezionare tramite mpi-selector l'implementazione "impi_32-3.2.1". Diversamente dal caso precedente non serve l'opzione "-m32" al compilatore, in quanto è inglobata nel wrapper mpicc. In effetti una volta selezionata la libreria MPI suddetta sia l'ambiente di compilazione che quello di esecuzione sono impostati per compilare ed eseguire codici a 32 bit. Per sottomettere sotto LSF un job che usi Intel MPI a 32 bit si procede in modo del tutto analogo ai codici a 64 bit. La forma del lanciatore per Intel MPI è descritta nel paragrafo: Sottomissione di un' job parallelo (MPI).

• 32 bit per librerie numeriche

Le librerie da linkare ai codici a 32 bit devono essere anche a 32 bit. Come detto la maggior parte delle librerie installate su Cresco sono presenti in entrambe le versioni (Per la lista delle librerie disponobili vedi QUI). Riportiamo il seguente esempio: ho un codice seriale Fortran90 che chiama una routine delle lapack, la "sgesv" che serve per la risoluzione di un sistema lineare tramite la fattorizzazione LU. Nell'esempio sotto uso il compilatore gfortran e la libreria lapack inclusa nella Intel MKL:
gfortran -m32 -o lapack_sgesv.x lapack_sgesv.f90 -L/opt/intel/mkl/10.1.1.019/lib/32 -lmkl_lapack95 -lmkl_intel -lmkl_sequential -lmkl_core

qui lapack_sgesv.x è il nome dell'eseguibile, lapack_sgesv.f90 è il sorgente fortran e mkl_intel, mkl_sequential, mkl_core sono alcune componenti di cui mkl_lapack95 necessita.

• 32 bit per MPI + librerie numeriche

Per un codice MPI che usi librerie, quali blas o lapack, ovviamente occorre combinare i due punti precedentemente discussi: selezionare la Intel MPI 32 bit e compilare il codice linkando le librerie opportune (per le Intel MKL queste stanno nella directory "/opt/intel/mkl/10.1.1.019/lib/32")

[sommario]


5. Links utili

Di seguito riportiamo links utili sia per le "User's Guide" dei compilatori, sia le "man pages" per i compilatori citati in questa sezione (accessibili o via Web oppure on-line digitando: "man gfortran" da una shell di CRESCO).

Librerie Disponibili su CRESCO

User's Guide Man Pages(solo alcuni comandi, vedi poi riferimenti all'interno) Librerie MPI

[sommario]


[top]


ultimo aggiornamento: 28/01/2016|e-mail: Salvatore Raia Fiorenzo Ambrosino