Oxygen HPC OpenMP fondamenti Carmine Spagnuolo
1 Oxygen HPC Cluster Oxygen Ambiente - Module Environment - Portable Batch System 2 OpenMP 31 fondamend Modello di esecuzione OpenMP core DireGve OpenMP Roadmap 2014 Università degli Studi di Salerno
1 Oxygen HPC Cluster Oxygen Ambiente - Module Environment - Portable Batch System 2 OpenMP 31 fondamend Modello di esecuzione OpenMP core DireGve OpenMP Roadmap 2014 Università degli Studi di Salerno
Hardware: 9 x DELL PowerEdge PowerEdge C6220: - Processors: 2 x Intel(R) Xeon E5-2680, 8C, 27GHz, 20M Cache, 8GT/s, 130W TDP, Turbo, HT,DDR3-800/1066/1333/1600 MHz; - Memory: 256GB DDR3; - Hard Drive: 6 x 1TB; - Network: 2 x Intel CorporaDon I350 Gigabit, 2 x Intel CorporaDon 82599EB 10- Gigabit SFI/SFP+ Oxygen 2014 Università degli Studi di Salerno
Hardware: 12 x GPU NVIDIA Tesla M2090: - CUDA Driver Version / RunDme Version: 55 / 55 - CUDA Capability Major/Minor version number: 20 - Total amount of global memory: 5GB - MulDprocessors, ( 32) CUDA Cores/MP: 512 CUDA Cores - GPU Clock rate: 1301 MHz (130 GHz) - Memory Clock rate: 1848 Mhz - Memory Bus Width: 384- bit - L2 Cache Size: 786432 bytes Oxygen 2014 Università degli Studi di Salerno
wwwisislabit:8092/phpldapadmin PBS ssh p 22103 user@wwwisislabit Oxygen 2014 Università degli Studi di Salerno
Nodi Oxygen: - Oxygen[1-8] - Oxygen1 (2 GPU) - Oxygen5 (8 GPU) SSH - ssh p 22103 user@wwwisislabit(17216151) SSH Key Exchange - ssh- keygen t rsa - cat ssh/id_rsa >> ssh/authorized_keys Oxygen - Ambiente 2014 Università degli Studi di Salerno
L ambiente utente è gesdto tramite: Environment Modules - hop://modulessourceforgenet/ Uno strumento per aiutare gli utend a gesdre il loro ambiente di shell Unix o Linux, permeoendo di gesdre le variabili di ambiente in modo dinamico Modules can be loaded and unloaded dynamically and atomically, in a clean fashion Oxygen - Module 2014 Università degli Studi di Salerno
Environment Modules: module [ switches ] [ sub- command ] [ sub- command- args ] sub- command 1 available (av) 2 load module- name 3 unload module- name 4 whads module- name 5 list 6 swap module- name1 module- name2 7 purge Oxygen - Module 2014 Università degli Studi di Salerno
Oxygen - Module
Ambiente di esecuzione: Portable Batch System (PBS) è un sistema di gesdone e controllo del carico su un insieme di nodi: Queuing Scheduling Monitoring PBS 2014 Università degli Studi di Salerno
Flow di esecuzione: - Creazione: script Unix per comunicare i vari parametri del job PBS: tempo di esecuzione (walldme), numero e caraoerisdche delle risorse e come eseguire il job - So9omissione: comando qsub [opdons] script_name - Esecuzione: verificato stato comando qstat [opdons] queue- name? - Finalizzazione: quando un job termina lo standard output ed error sono salvad in file e copiad nella cartella dalla quale il job è stato sooomesso PBS 2014 Università degli Studi di Salerno
Job flow: - Creazione - Sooomissione DireGve: - #PBS - l walldme=hh:mm:ss - #PBS - l pmem=size- GB - #PBS - l nodes=n:ppn=m (N può essere un pardcolare nodo del sistema) - #PBS - q queuename - #PBS j file_name Modalità interagva: - qsub - I - l nodes=1:ppn=1 - l walldme=4:00:00 PBS 2014 Università degli Studi di Salerno
Job flow: - Creazione: script Unix per comunicare i vari parametri del job PBS: tempo di esecuzione (walldme), numero e caraoerisdche delle risorse e come eseguire il job PBS 2014 Università degli Studi di Salerno
TORQUE PBS, basato sul progeoo PBS originale (OpenPBS, NASA Ames Research Center): - hop://wwwadapdvecompudngcom/products/open- source/torque/ - hop://wwwadapdvecompudngcom/support/download- center/torque- download/ - Feature: 1 Fault Tolerance 2 Scheduling Interface 3 Scalability 4 Usability PBS TORQUE MAUI Scheduler 2014 Università degli Studi di Salerno
MAUI scheduler: - hop://wwwadapdvecompudngcom/products/open- source/maui/ (registrazione) - Features: 1 Scalability 2 Rich administrator dashboard tools 3 Simplified HPC job submission and management 4 Grid and muld- cluster workload management capabilides 5 Enforce usage accoundng budgets or provide pay- for use PBS TORQUE MAUI Scheduler 2014 Università degli Studi di Salerno
TORQUE PBS installazione: /configure - - with- default- server=one - - with- server- home=/oxygen/var/ spool/pbs - - with- rcp=scp - - with- debug - - enable- nvidia- gpus - - with- nvml*- include=/oxygen/compilers/cuda/55/include - with- nvml- lib=/oxygen/ compilers/cuda/55/lib64 2>&1 tee configure_torquelog make j numero_di_processi make packages torque- package- clients- linux- x86_64sh - - install torque- package- devel- linux- x86_64sh install (solo head node) torque- package- doc- linux- x86_64sh install (solo head node) torque- package- mom- linux- x86_64sh - - install torque- package- server- linux- x86_64sh install (solo head node) trucco echo /opt/torque/lib > /etc/ldsoconfd/torqueconf *NVIDIA Management Library (NVML): A C- based API for monitoring and managing various states of the NVIDIA GPU devices PBS TORQUE MAUI Scheduler 2014 Università degli Studi di Salerno
MAUI scheduler installazione: /configure - - with- pbs=/opt/torque - - with- spooldir=/opt/maui make j numero_di_processi make install Configurazione ambiente PBS e MAUI: oxyegn_set_envsh in /etc/profiled/ #oxygen setup /etc/profiled/modulessh export PATH=$PATH:/opt/torque/bin:/opt/torque/sbin:/opt/maui/sbin:/ opt/maui/bin NOTE OpenMPI /configure - - prefix=/oxygen/compilers/mpi/openmpi/182- - java- - oracle- 160_25 - - enable- mpi- java - - with- jdk- bindir=/oxygen/compilers/java/oracle/160_25/bin - - with- jdk- headers=/oxygen/compilers/java/oracle/160_25/include - - with- tm=/opt/torque - - enable- mpi- thread- muluple PBS TORQUE MAUI Scheduler 2014 Università degli Studi di Salerno
Tempi di esecuzione: UDlizzare le API disponibili nella piaoaforma udlizzata Soluzione Veloce- Veloce Ume ls ac aout myjoberr real 0m0004s wall clock Dme (from start to finish the call) user 0m0003s CPU Dme (user- mode code) sys 0m0000s - CPU Dme (kernel code) user+sys CPU total Ume Oxygen performance 2014 Università degli Studi di Salerno
PBS Demo
1 Oxygen HPC Cluster Oxygen Ambiente 1 Oxygen HPC Cluster Oxygen Module Environment - Portable Batch System 2 OpenMP 31 fondamenu Roadmap 2014 Università degli Studi di Salerno
OpenMP (Open MulDprocessing) è un API muldpiaoaforma per la creazione di applicazioni parallele su sistemi a memoria condivisa (Fortran, C e C++) L obiegvo principale di OpenMP è quello di semplificare lo sviluppo di applicazioni muldthread RiferimenD: hop://openmporg/ hop://openmporg/mp- documents/omp- hands- on- SC08pdf Common Mistakes in OpenMP and How To Avoid Them A CollecUon of Best PracUces, Michael Süß and Claudia Leopold OpenMP 31 2014 Università degli Studi di Salerno
Compilatori: GNU: gcc 42 in poi [- fopenmp] Oracle [- xopenmp] Intel [- Qopenmp or openmp] PGI (Portland Group Compilers and Tools) [- mp] hop://openmporg/wp/openmp- compilers/ OpenMP 31 2014 Università degli Studi di Salerno
OpenMP 31
OpenMP 31
OpenMP 31
OpenMP core syntax I costrug udlizzad in OpenMP sono diregve al compilatore: #pragma omp construct [clause [clause] ] Esempio: #pragma omp parallel num_threads(4) ProtoDpi delle funzioni e i Dpi: #include <omph> Compilazione GCC: gcc - fopenmp hellompc - o helloout HelloWorld Example: #ifdef _OPENMP #include <omph> #endif void main() { #pragma omp parallel { int ID=omp_get_thread_num(); prin ( hello(%d),id); prin ( world(%d)\n,id); hello(3)hello(1)hello(5)world(5) hello(0)world(0) world(3) world(1) hello(2)world(2) hello(4)world(4) OpenMP 31
OpenMP Creazione dei Thread Fork- Join Parallelism: il master thread distribuisce un team di thread dinamicamente OpenMP Fork-Join Parallelism 2014 Università degli Studi di Salerno
OpenMP Fork-Join model
OpenMP creazione dei Thread Il construoo parallel consente di creare i thread Definizione del numero di thread: 1 Clausola alla diregva parallel: #pragma omp parallel num_threads(4); 2 RunDme funcdon: omp_set_thread_num(x); 3 Environment variable: export OMP_NUM_THREADS=x Example: #ifdef _OPENMP #include <omph> #endif void main() { double A[1000]; omp_set_num_threads(4); #pragma omp parallel { int ID=omp_get_thread_num(); func(id,a); BARRIER prin ( all done\n ); OpenMP 31
OpenMP sincronizzazione DireGve: cridcal atomic barrier ordered flush lock (simple e nested) In presuto da Golang OpenMP 31
OpenMP sincronizzazione DireGve: criucal solo un thread alla volta entra nella regione cridca atomic barrier ordered flush lock (simple e nested) criucal Example: float res; #pragma omp parallel { float B; int i,id,nthrds; id=omp_get_thread_num(); nthrds=omp_get_num_threads(); for(i=id;i<niters;i+nthrds){ B=big_job(); #pragma omp criucal cosume(b,res); I thread aoendono il loro turno e solo un thread alla volta chiama la consume OpenMP 31
OpenMP sincronizzazione DireGve: cridcal atomic operazioni in mutua esclusione barrier ordered flush lock (simple e nested) atomic Example: #pragma omp parallel { double tmp, B; B = DOIT(); tmp = big(b); #pragma omp atomic X += tmp; Operazione atomica solo sulla leoura/ aggiornamento di X OpenMP 31
OpenMP sincronizzazione DireGve: cridcal atomic barrier ogni thread aoende finché tug non raggiungono la barriera ordered flush lock (simple e nested) barrier Example: #pragma omp parallel { #pragma omp master prin ( I am the MASTER\n ); prin ( ID %d,id); #pragma omp barrier prin ( all done\n ); OpenMP 31
OpenMP sincronizzazione DireGve: cridcal atomic Barrier ordered flush lock (simple e nested) OpenMP 31 ordered Example: int i=0; #pragma omp parallel for schedule(stauc)\ ordered for ( i = 0; i <= 10; ++i) { // Do something here #pragma omp ordered prin ("test() iteradon %d\n", i); test() iteradon 0 test() iteradon 1 test() iteradon 2 test() iteradon 3 test() iteradon 4 test() iteradon 5 test() iteradon 6 test() iteradon 7 test() iteradon 8 test() iteradon 9 test() iteradon 10
OpenMP sincronizzazione DireGve: cridcal atomic barrier ordered flush lock (simple e nested) flush Example: double A; A = compute(); flush(a); // flush to memory to make sure other // threads can pick up the right value Definisce un sequence point dove ad ogni thread è garandta la consistenza della memoria OpenMP 31
OpenMP sincronizzazione DireGve: cridcal atomic barrier ordered flush lock (simple e nested) Modello di memoria: Relaxed Consistency Variante della weak consistency Le operazioni S rispeoano l ordine sequenziale in ogni thread Le operazioni di W e R non possono essere riordinate rispeoo le operazioni S: S W, S R, R S, W S, S S (S=sincronizzazione, W=write e R=read) OpenMP 31
OpenMP sincronizzazione DireGve: cridcal atomic barrier ordered flush lock (simple e nested) simple lock Example: Il rilascio del lock implica il flush delle variabili visibili da tug I thread omp_lock_t lck; omp_init_lock(&lck); #pragma omp parallel private (tmp, id) { id = omp_get_thread_num(); tmp = do_lots_of_work(id); omp_set_lock(&lck); prin ( %d %d, id, tmp); omp_unset_lock(&lck); omp_destroy_lock(&lck); OpenMP 31
OpenMP Worksharing Consentono la distribuzione dell esecuzione di una regione di codice (in a clever fashion) Worksharing: 1 loop 2 secdons/secdon 3 single 4 task Barriera implicita in uscita ma non in ingresso (clausola nowait può eliminarla) OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 Single 4 task La variabile i diventa automadcamente privata ad ogni thread, ciò può anche essere realizzato tramite la clausola private(i) for Example: #pragma omp parallel { #pragma omp for for (i=0;i<n;i++){ independent_work(i); OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 Single 4 task Clausola schedule: StaDc: esecuzione divisa in chunk, assegnazione round- robin Dynamic: ogni thread richiede un chunk alla volta Guided: esecuzione divisa in chuck di taglia differente, assegnazione dinamica (caso speciale Dynamic) Run- Dme: controllato da variabili di ambiente OpenMP 31 for Example: Codice sequenziale: for (i=0;i<n;i++){ a[i]=a[i]+b[i]; Single Program MulCple Data: #pragma omp parallel { int id, i, Nthrds, istart, iend; id = omp_get_thread_num(); Nthrds = omp_get_num_threads(); istart = id * N / Nthrds; iend = (id+1) * N / Nthrds; if (id == Nthrds- 1) iend = N; for(i=istart;i<iend;i++) {a[i]=a[i]+b[i]; Worksharing: #pragma omp parallel schedule(stauc,1) { #pragma omp for for (i=0;i<n;i++){ work(i);
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 Single 4 Task Trucco per testare la dipendenza: Verificare che un loop sequenziale produca lo stesso risultato in reverse order OpenMP 31 for Example: int i, j, A[MAX]; j = 5; for (i=0;i< MAX; i++) { j +=2; A[i] = big(j); int i, A[MAX]; #pragma omp parallel for for (i=0;i< MAX; i++) { int j = 5 + 2*i; A[i] = big(j); Data dependencies: A[0] = 0; A[1] = 1; for(i = 3; i < 99; i++){ A[i] = A[i- 1] + A[i- 2];
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 single 4 task Clausola collapse(n) for Example: NO error nested loop #pragma omp parallel { #pragma omp for for (i=0;i<n;i++){ #pragma omp for for (j=0;j<n;j++){ work(i,j); #pragma omp parallel for collapse(2) for (i=0;i<n;i++){ for (j=0;j<n;j++){ work(i,j); OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 single 4 task Clausola reducdon(op,var): op: +, -, *, MIN,MAX var: shared Viene creata una copia locale della variabile (inizializzata in modo appropriato +,0 *,1 +,0) alla terminazione della regione parallela viene aggiornato il valore della variabile condivisa for Example: double ave=00, A[MAX]; int i; for (i=0;i< MAX; i++) { ave + = A[i]; ave = ave/max; double ave=00, A[MAX]; int I; #pragma omp parallel for reducuon (+:ave) for (i=0;i< MAX; i++) { ave + = A[i]; ave = ave/max; OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secuons/secuon 3 single 4 task OpenMP 31 for Example: int main() { #pragma omp parallel secuons\ num_threads(4) { prin ("Hello from thread OUT %d\n", omp_get_thread_num()); prin ("Hello from thread OUT %d\n", omp_get_thread_num()); #pragma omp secuon prin ("Hello from thread %d\n", omp_get_thread_num()); #pragma omp secuon prin ("Hello from thread %d\n", omp_get_thread_num()); #pragma omp secuon Hello from thread 0 prin ("Hello from thread %d\n", Hello from thread 0 omp_get_thread_num()); Hello from thread OUT 3 #pragma omp secuon Hello from thread OUT 3 prin ("Hello from thread %d\n", Hello from thread 1 omp_get_thread_num()); Hello from thread 2
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 single 4 task Denota un blocco di codice eseguibile da un solo thread single Example: #pragma omp parallel { do_many_things(); #pragma omp single { exchange_boundaries(); do_many_other_things(); Alla terminazione del blocco è presente una barriera implicita OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 single 4 task DireGva introdooa in OpenMp 30 e migliorata in 31 e 40 Task sono unità di lavoro indipendend Ogni task viene assegnato a un thread Il rundme system decide dinamicamente come eseguire i task OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 single 4 task Un thread prepara l esecuzione dei task: packaging (code and data) execudon (un thread del team esegue il task) I task sono gesdd in una coda OpenMP garandsce che alla terminazione della regione parallela ogni task è terminato OpenMP 31
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 Single 4 task La diregva task è udle per la parallelizzazione di paoern irregolari e funzioni ricorsive Soluzione 1: Troppa sincronizzazione (nested parallel regions) Poca flessibilità OpenMP 31 task Example: Soluzione 1: void preorder(node *p) { process(p- >data); #pragma omp parallel secuons if (p- >le ) #pragma omp secuon preorder(p- >le ); if (p- >right) #pragma omp secuon preorder(p- >right); Soluzione 2: void preorder (node *p) { process(p- >data); If (p- >le ) #pragma omp task preorder(p- >le ); if (p- >right) #pragma omp task preorder(p- >right);
OpenMP Worksharing Worksharing: 1 loop 2 secdons/secdon 3 Single 4 task Sincronizzazione task: taskwait task Example: void traverse(node *p) { If (p- >le ) #pragma omp task traverse(p- >le ); if (p- >right) #pragma omp task traverse(p- >right); if(postorder) #pragma omp taskwait process(p- >data); OpenMP 31
OpenMP RunUme Library Modificare/Verificare il numero di thread: - omp_set_num_threads(n) - omp_get_num_threads() - omp_get_thread_num() - omp_get_max_threads() Regione parallela? - omp_in_parallel() GesDone dinamica del numero di thread tra le regioni parallele: - omp_set_dynamic() - omp_get_dynamic() Numero di processori disponibili? - omp_num_procs() OpenMP 31
OpenMP Data sharing Nei costrug è possibile definire la visibilità delle variabili: shared private firstprivate, privata ma inizializzata col valore della variabile prima della regione parallela Thread number: 5 x: 5 lastprivate, privata ma alla terminazione della regione Thread number: 9 x: 9 parallela il valore è quello dell uldma Thread number: iterazione 4 x: 4 OpenMP 31 lastprivate Example: x=44; #pragma omp parallel for lastprivate(x) for(i=0;i<=10;i++){ x=i; prin ("Thread number: %d x: %d \n",omp_get_thread_num(),x); prin ("x is %d\n", x); Thread number: 1 Thread number: 2 Thread number: 7 Thread number: 3 Thread number: 8 Thread number: 10 Thread number: 0 Thread number: 6 x is 10 x: 1 x: 2 x: 7 x: 3 x: 8 x: 10 x: 0 x: 6
PADABS 2014 Università degli Studi di Salerno
wwwdmasonorg wwwisislabit spagnulocarmine@gmailcom