Sign in to follow this  
DarwinNE

Calcolo scientifico ad alte prestazioni

Recommended Posts

Ciao a tutti,

da ormai diversi anni mi trovo confrontato con alcuni problemini di calcolo numerico (in particolare, relativi a dei fenomeni di diffusione ed a dei problemi agli autovalori).

Vorrei aprire qui una discussione per riportare alcune cosette di cui mi sono reso conto utilizzando il Fortran e LAPACK. Proporrei a chi volesse di continuare la discussione riportando tecniche particolari, risultati interessanti o strategie da applicare in casi peculiari, nonché risultati di benchmark.

Per chi non lo sapesse, LAPACK (Linear Algebra PACKage, http://www.netlib.org/lapack/ ) è una collezione di routine che permettono di affrontare in maniera molto efficace una collezione molto vasta di problemi legati all'algebra lineare. Probabilmente, si tratta di un condensato di quanto è stato fatto di meglio nel campo negli ultimi 50 anni.

Una caratteristica di LAPACK è di appoggiarsi su BLAS (Basic Linear Algebra Subprograms, http://www.netlib.org/blas/), che provvede a fornire i "mattoni di base", ovvero gli algoritmi a basso livello che vengono poi usati da LAPACK. Questo consente di mantenere il codice di LAPACK abbastanza generale, utilizzando però implementazioni di BLAS altamente ottimizzate su un'archittetura specifica. ATLAS (Automatically Tuned Linear Algebra Software: http://math-atlas.sourceforge.net/) è una versione di BLAS che in fase di configurazione e compilazione cerca di determinare strategie ottimizzate per ottenere i migliori risultati su un sistema qualunque.

Apple non fornisce un compilatore Fortran 77, ma lo si può facilmente installare (g77 o meglio g95 oppure gfortran). Nel mio caso, ho usato g77.

Di contro, Apple fornisce il framework vecLib (http://developer.apple.com/hardwaredrivers/ve/vector_libraries.html) che è un ambiente ottimizzato per effettuare calcoli numerici e che comprende BLAS e LAPACK.

Il programma che ho usato per esempio crea semplicemente una matrice complessa di dimensione NMAX, la riempie con dei dati casuali e chiama la routine ZGEEV per calcolare autovalori ed autovettori. Il programma si chiama test.f ed è adattato da un esempio fornito dal NAG:

*     NAG Copyright 2005.*     .. Parameters ..      INTEGER          NIN, NOUT      PARAMETER        (NIN=5,NOUT=6)      INTEGER          NB, NMAX      PARAMETER        (NB=64,NMAX=1000)      INTEGER          LDA, LDVR, LWORK      PARAMETER        (LDA=NMAX,LDVR=NMAX,LWORK=(1+NB)*NMAX)*     .. Local Scalars ..      INTEGER          I, IFAIL, INFO, J, LWKOPT, N*     .. Local Arrays ..      COMPLEX *16      A(LDA,NMAX), DUMMY(1,1), VR(LDVR,NMAX), W(NMAX),     +                 WORK(LWORK)      DOUBLE PRECISION RWORK(2*NMAX)*     .. External Subroutines ..      EXTERNAL         ZGEEV*     .. Executable Statements ..      WRITE (NOUT,*) 'ZGEEV Example Program Results'*      WRITE (NOUT,*) 'Enter the size of the problem' *      READ (NIN,*) N	  N=NMAX      IF (N.LE.NMAX) THEN**        Create a random matrix*	         CALL SRAND(1)         DO I=1,N,1         	DO J=1,N,1         		A(I,J)=COMPLEX(RAND(),RAND())         	ENDDO         ENDDO*	*        Compute the eigenvalues and right eigenvectors of A*		         WRITE (NOUT,*) 'Begin of eigenvalue calculation'         CALL ZGEEV('No left vectors','Vectors (right)',N,A,LDA,W,DUMMY,     +              1,VR,LDVR,WORK,LWORK,RWORK,INFO)         LWKOPT = WORK(1)         WRITE (NOUT,*) 'End of eigenvalue calculation'*         IF (INFO.EQ.0) THEN**           Print solution*            WRITE (NOUT,*) 'Eigenvalues'            WRITE (NOUT,99999) (W(J),J=1,N)*            WRITE (NOUT,*)            IFAIL = 0         ELSE            WRITE (NOUT,*)            WRITE (NOUT,99998) 'Failure in ZGEEV.  INFO = ', INFO         END IF**        Print workspace information*         IF (LWORK.LT.LWKOPT) THEN            WRITE (NOUT,*)            WRITE (NOUT,99997) 'Optimum workspace required = ', LWKOPT,     +        'Workspace provided         = ', LWORK         END IF      ELSE         WRITE (NOUT,*) 'NMAX too small'      END IF      STOP*99999 FORMAT ((3X,4(' (',F7.4,',',F7.4,')',))99998 FORMAT (1X,A,I4)99997 FORMAT (1X,A,I5,/1X,A,I5)      END

Ho compilato ed eseguito il codice su un MacBook Core Duo, con 1 GiB di RAM:

*     Version du système :	Mac OS X 10.4.11 (8S2167)*     Nom du modèle :	MacBook*     Identifiant du modèle :	MacBook1,1*     Nom du processeur :	Intel Core Duo*     Vitesse du processeur :	2 GHz*     Nombre de processeurs :	1*     Nombre total de noyaux :	2*     Cache de niveau 2 (par processeur) :	2 Mo*     Mémoire :	1 Go*     Vitesse du bus :	667 MHz*     Version de la ROM de démarrage :	MB11.0061.B03*     Version SMC :	1.4f12
(ho il sistema operativo in francese, ma si dovrebbe capire lo stesso)

Per la compilazione ed il link, ho seguito tre possibilità: la versione standard (non ottimizzata di BLAS), ATLAS ed il framework vecLib. Ecco i comandi che ho usato da terminale nei tre casi:

ATLAS: g77 test.f lapack_i686-apple-darwin8.7.1.a libf77blas.a libatlas.a -o testBLAS: g77 test.f lapack_i686-apple-darwin8.7.1.a libblas_i686-apple-darwin8.7.1.a -o testApple vecLib: g77 test.f -o test -Wl,-framework -Wl,vecLib

La libreria lapack_i686-apple-darwin8.7.1.a viene generata durante la compilazione di LAPACK e contiene le funzioni di questo pacchetto.

La libreria libf77blas.a è la libreria di interfaccia tra ATLAS ed il Fortran 77, mentre libatlas.a contiene la versione ottimizzata di ATLAS realizzata sulla mia macchina.

libblas_i686-apple-darwin8.7.1.a è la libreria statica fornitami dalla compilazione di BLAS (non ottimizzata) sulla mia macchina.

Se tutto va a buon fine, si ottiene un file eseguibile "test" di cui si può misurare la velocità di esecuzione con il comando seguente:

time ./test
Ovviamente, meno ci mette il programma, meglio è!

Ed ecco i risultati, per alcuni versi piuttosto sorprendenti (ma come tutti i benchmark, da prendere con le pinze):

* -----------------------------------------------------------------------------*     Size          Memory          Time        Processor       BLAS* -----------------------------------------------------------------------------*     1000         31.97           1m0148s     99%             Standard*     1000         31.99           58.4s       99%             Standard*     1000         32.22           49s         99%             ATLAS*     1000         32.83           1m35s       99%             vecLib  *     2000         62.95           7m8.301s    99%             Standard*     2000         124.02          7m0.707s    99%             Standard*     2000         140.90          13m10.216s  99%             vecLib*     3200         158.76          23m54.008s  99%             Standard

La dimensione (Size) è il valore di NMAX fissato con il comando FORTRAN 77

PARAMETER        (NB=64,NMAX=1000)

Quello che mi stupisce è che la versione linkata con vecLib (che dovrebbe essere ottimizzata da Apple per le sue macchine), almeno per il calcolo di autovalori e autovettori di una matrice 1000x1000 è quasi due volte più lenta di quanto si ottiene con ATLAS (1m35s contro 49s), mentre la versione non ottimizzata di BLAS non si comporta poi male con i suoi 58,4s. La stessa tendenza è confermata da un test su una matrice 2000x2000: bisogna proprio evitare vecLib!

Forse è dovuto al fatto che si trattava di un framework ottimizzato per PowerPC? Devo ancora fare delle prove serie con l'iMac G5.

Voi cosa ne pensate? Avete avuto esperienze di questo tipo? Vi capita di trattare questo tipo di problemi? Vi trovate bene sul Macintosh?

Share this post


Link to post
Share on other sites

credo proprio sia così.

scusa una cosa: hai esperienza di g95 su leopard? al'va no!!! :confused:

No, non utilizzo ancora Leopard.

Piuttosto, sono *molto* interessato a comparazioni fra i vari compilatori Fortran. In particolare, come si comportano g95 e gfortran rispetto a g77?

Mi sembra di aver capito che per gfortran si trovano facilmente dei pacchetti o comunque qualcosa che ne semplifica l'installazione. In questa pagina, c'è qualcosa:

http://hpc.sourceforge.net/

gfortran dovrebbe poter sostituire g95 per il Fortran 95.

Una cosa che osservo è che pure avendo una macchina dual core, l'occupazione massima è sempre del 99% (a meno di un guizzo a 140% utilizzando vecLib), il che mi porta a pensare che il codice generato nel mio caso resta sempre seriale (e difatti, c'è un solo thread).

Share this post


Link to post
Share on other sites

g77 non ha vantaggi rispetto a gfortran, che in effetti può compilare anche Fortran77 senza problemi. g77 non è più supportato o sviluppato.

Per avere codice che sfrutti più processori, o leggete qui e connessi

http://gcc.gnu.org/projects/tree-ssa/vectorization.html

oppure usate OpenMP, che con delle semplicissime modifiche al sorgente permette l'utilizzo di più processori.

http://en.wikipedia.org/wiki/OpenMP

In ogni modo, gcc 4.3 che trovate su hpc.sf.net deve essere chiamato con specifici livelli di ottimizzazione e opzioni, altrimenti non vettorizza. Sarà simile anche col gfortran, penso.

Nota: GCC 4.3 è ora definitivo, la beta del sito hpc.sf.net è quindi vecchia. Attendete la nuova versione o ricompilatevi il compilatore da soli (... impiegò un pomeriggio sul mio vecchio iBook).

Magari questa sera facciamo qualche prova.

Share this post


Link to post
Share on other sites

In ogni modo, gcc 4.3 che trovate su hpc.sf.net deve essere chiamato con specifici livelli di ottimizzazione e opzioni, altrimenti non vettorizza. Sarà simile anche col gfortran, penso.

Nota: GCC 4.3 è ora definitivo, la beta del sito hpc.sf.net è quindi vecchia. Attendete la nuova versione o ricompilatevi il compilatore da soli (... impiegò un pomeriggio sul mio vecchio iBook).

In effetti, il risultato di un tentativo di installazione di GCC 4.3 a partire della beta che si trova sul sito hpc non ha dato buoni risultati...

Share this post


Link to post
Share on other sites

In effetti, il risultato di un tentativo di installazione di GCC 4.3 a partire della beta che si trova sul sito hpc non ha dato buoni risultati

? è vecchio, ma funzionava benissimo l'ultima volta che l'ho usato su Tiger. Ho avuto più problemi con Leopard.

L'hai decompresso correttamente? devi poi cambiare la path, a seconda di come lo vuoi usare (primario o meno).

Share this post


Link to post
Share on other sites

L'hai decompresso correttamente? devi poi cambiare la path, a seconda di come lo vuoi usare (primario o meno).

Ehm... cambiare la path come??? Ho fatto delle prove, perché non mi trovava cc1, ma è stato un disastro. Inoltre, mi piacerebbe poter scegliere che versione di gcc utilizzare (quella più tradizionale, mi pare la 4.0, oppure l'ultima con la vettorizzazione attivata).

Share this post


Link to post
Share on other sites

Lo scrivo esplicitamente, visto che praticamente tutti quelli che hanno problemi con i compilatori di hpc.sf.net hanno fatto il seguente errore:

per installare i suoi compilatori dovete ESATTAMENTE eseguire quello che vi viene indicato nel sito… scaricare alla cieca e poi fare doppio clic non va bene.

La riga di comando da eseguire è:

sudo tar -xvf gcc-bin.tar -C /

Anche io feci l'errore la prima volta, però poi tornai indietro a leggere e mi avvidi dell'errore :-)

In merito alla path, invece, è necessario che il compilatore che intendete usare abbia la precedenza rispetto agli altri. Se volete usare gcc-43 dovrete allora mettere nella variabile d'ambiente $PATH /usr/local/bin prima di /usr/bin. L'inverso per tornare a usare il compilatore di sistema. Se volete usare solo gfortran non serve, non ve ne sono preinstallati.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this