2016-06-16 43 views
23

Sto provando a configurare un ambiente per supportare l'analisi dei dati esplorativa su un cluster. Sulla base di un'indagine iniziale su ciò che è fuori là, il mio obiettivo è utilizzare Scala/Spark con Amazon EMR per eseguire il provisioning del cluster.Come configurare BLAS/LAPACK ad alte prestazioni per Breeze su Amazon EMR, EC2

Attualmente sto solo cercando di ottenere alcuni esempi di base in esecuzione per verificare che tutto sia configurato correttamente. Il problema che sto avendo è che non vedo le prestazioni che mi aspetto dalle librerie BLAS Atlas nell'istanza della macchina Amazon.

Di seguito è riportato uno snippet di codice del mio benchmark semplice. E 'solo una matrice quadrata moltiplicata seguita da un breve ingrassamento multiplo e un alto e sottile multiplo per produrre una piccola matrice che può essere stampata (volevo essere sicuro che Scala non saltava alcuna parte del calcolo a causa di una valutazione lenta).

sto usando Breeze per la libreria di algebra lineare e netlib-java per tirare nelle librerie native locali per BLAS/LAPACK

import breeze.linalg.{DenseMatrix, DenseVector} 
import org.apache.spark.annotation.DeveloperApi 
import org.apache.spark.rdd.RDD 
import org.apache.spark.{Partition, SparkContext, TaskContext} 
import org.apache.spark.SparkConf 

import com.github.fommil.netlib.BLAS.{getInstance => blas} 

import scala.reflect.ClassTag 

object App { 

    def NaiveMultiplication(n: Int) : Unit = { 

    val vl = java.text.NumberFormat.getIntegerInstance.format(n) 
    println(f"Naive Multipication with vector length " + vl) 

    println(blas.getClass().getName()) 

    val sm: DenseMatrix[Double] = DenseMatrix.rand(n, n) 
    val a: DenseMatrix[Double] = DenseMatrix.rand(2,n) 
    val b: DenseMatrix[Double] = DenseMatrix.rand(n,3) 

    val c: DenseMatrix[Double] = sm * sm 
    val cNormal: DenseMatrix[Double] = (a * c) * b 

    println(s"Dot product of a and b is \n$cNormal") 
    } 

Sulla base di un sondaggio web di benchmark mi aspetto una matrice 3000x3000 moltiplicare per prendere ca. 2-4s utilizzando una libreria BLAS nativa ottimizzata. Quando eseguo localmente sul mio MacBook Air questo benchmark termina tra 1.8 secondi. Quando lo eseguo su EMR, termina tra ca. 11s (usando un'istanza g2.2xlarge, sebbene siano stati ottenuti risultati simili su un'istanza m3.xlarge). Come altro controllo incrociato, ho eseguito un AMI EC2 precostruito dallo BIDMach project sullo stesso tipo di istanza EC2, g2.2xlarge e ottenuto 2,2 s (nota, il benchmark GPU per lo stesso calcolo ha generato 0,047 s).

A questo punto ho il sospetto che netlib-java non stia caricando la libreria corretta, ma questo è il punto in cui sono bloccato. Ho passato attraverso il file README NetLib-java molti times e sembra le librerie ATLAS sono già installati come prescritto (vedi sotto)

[[email protected] ~]$ ls /usr/lib64/atlas/ 
libatlas.a  libcblas.a  libclapack.so  libf77blas.so  liblapack.so  libptcblas.so  libptf77blas.so 
libatlas.so  libcblas.so  libclapack.so.3 libf77blas.so.3 liblapack.so.3 libptcblas.so.3 libptf77blas.so.3 
libatlas.so.3 libcblas.so.3 libclapack.so.3.0 libf77blas.so.3.0 liblapack.so.3.0 libptcblas.so.3.0 libptf77blas.so.3.0 
libatlas.so.3.0 libcblas.so.3.0 libf77blas.a  liblapack.a  libptcblas.a  libptf77blas.a 
[[email protected] ~]$ cat /etc/ld.so.conf 
include ld.so.conf.d/*.conf 
[[email protected] ~]$ ls /etc/ld.so.conf.d 
atlas-x86_64.conf kernel-4.4.11-23.53.amzn1.x86_64.conf kernel-4.4.8-20.46.amzn1.x86_64.conf mysql55-x86_64.conf R-x86_64.conf 
[[email protected] ~]$ cat /etc/ld.so.conf.d/atlas-x86_64.conf 
/usr/lib64/atlas 

Qui di seguito ho Mostra 2 esempi che eseguono il punto di riferimento su istanza Amazon EMR. Il primo mostra quando il sistema nativo BLAS si carica apparentemente correttamente. Il secondo mostra quando il BLAS nativo non viene caricato e il pacchetto ricade sull'implementazione di riferimento. Quindi sembra che stia caricando un BLAS nativo in base ai messaggi e ai tempi. Rispetto all'esecuzione locale sul mio Mac, il caso BLAS non viene eseguito all'incirca nello stesso tempo, ma il caso BLAS nativo viene eseguito in 1.8 secondi sul mio Mac rispetto ai 15 secondi nel caso in basso. I messaggi informativi sono gli stessi per il mio Mac rispetto a quelli EMR (diversi da nomi di file/dir specifici, ecc.).

[[email protected] ~]$ spark-submit --class "com.cyberatomics.simplespark.App" --conf "spark.driver.extraClassPath=/home/hadoop/simplespark-0.0.1-SNAPSHOT-jar-with-dependencies.jar" --master local[4] simplespark-0.0.1-SNAPSHOT-jar-with-dependencies.jar 3000 naive 
Naive Multipication with vector length 3,000 
Jun 16, 2016 12:30:39 AM com.github.fommil.jni.JniLoader liberalLoad 
INFO: successfully loaded /tmp/jniloader2856061049061057802netlib-native_system-linux-x86_64.so 
com.github.fommil.netlib.NativeSystemBLAS 
Dot product of a and b is 
1.677332076284315E9 1.6768329748988206E9 1.692150656424957E9 
1.6999000993276503E9 1.6993872020220244E9 1.7149145239563465E9 
Elapsed run time: 15.1s 
[[email protected] ~]$ 
[[email protected] ~]$ spark-submit --class "com.cyberatomics.simplespark.App" --master local[4] simplespark-0.0.1-SNAPSHOT-jar-with-dependencies.jar 3000 naive 
Naive Multipication with vector length 3,000 
Jun 16, 2016 12:31:32 AM com.github.fommil.netlib.BLAS <clinit> 
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLAS 
Jun 16, 2016 12:31:32 AM com.github.fommil.netlib.BLAS <clinit> 
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeRefBLAS 
com.github.fommil.netlib.F2jBLAS 
Dot product of a and b is 
1.6640545115052865E9 1.6814609592261212E9 1.7062846398842275E9 
1.64471099826913E9 1.6619129531594608E9 1.6864479674870768E9 
Elapsed run time: 28.7s 

A questo punto la mia ipotesi migliore è che in realtà è un caricando lib nativa, ma si sta caricando un generico. Qualche suggerimento su come posso verificare quale libreria condivisa sta raccogliendo in fase di esecuzione? Ho provato 'ldd' ma sembra non funzionare con spark-submit. O forse le mie aspettative per Atlas sono sbagliate, ma sembra difficile credere che AWS preinstallerebbe le librerie se non avessero una velocità ragionevolmente competitiva.

Se si nota che le librerie non sono collegate correttamente su EMR, fornire indicazioni su ciò che è necessario fare affinché le librerie Atlas vengano rilevate da netlib-java.

grazie tim

+1

Potresti convertire "follow-up" in una risposta? Fornisce spunti utili e se non ci saranno altre risposte mi piacerebbe assegnare la taglia. Grazie in anticipo! –

+0

Non riesco nemmeno a ricreare la prima istanza in cui si inserisce la lib nativa di EMR Atlas predefinita. Hai fatto altre cose in modo diverso (non elencato nel tuo post) che ha causato l'utilizzo della lib nativa al posto di F2jBLAS? Non importa cosa cerco, mi sembra di avere ancora F2J. –

+0

È passato molto tempo da quando ho guardato questo. Penso che il modo in cui netlib è integrato con Breeze sia cambiato un po '. Ma, come ricordo, la chiave per superare il problema era includere il .jar che contiene gli stub della libreria nativa. Nel momento in cui per la prima volta ho postato quanto sopra, il jar HAD deve essere incluso esplicitamente con una variabile di percorso aggiuntiva. NON è stato incluso nel barattolo di grasso con la mia applicazione. Ecco un buon post sull'impostazione di netlib per usare BLAS https://datasciencemadesimpler.wordpress.com/tag/blas/ –

risposta

10

Follow up:

mia conclusione provvisoria è che le librerie Atlas installati di default per l'istanza Amazon EMR è semplicemente lenta. O è una build generica che non è stata ottimizzata per il tipo di macchina specifico, o è fondamentalmente più lenta di altre librerie.Usando questo script come guida ho costruito e installato OpenBLAS per il tipo di macchina specifico in cui stavo eseguendo i benchmark (ho trovato anche alcune informazioni utili here). Dopo l'installazione di OpenBLAS, il mio benchmark a matrice multipla 3000x3000 è stato completato in 3,9 secondi (rispetto ai 15,1 elencati sopra quando si utilizzano le librerie Atlas predefinite). Questo è ancora più lento dello stesso benchmark eseguito sul mio Mac (di un fattore x2), ma questa differenza si riduce in un intervallo che potrebbe essere credibilmente dovuto alle prestazioni h/w sottostanti.

Ecco una lista completa dei comandi che ho usato per installare OpenBLAS librerie su EMR di Amazon, Spark esempio:

sudo yum install git 
git clone https://github.com/xianyi/OpenBlas.git 
cd OpenBlas/ 
make clean 
make -j4 
sudo mkdir /usr/lib64/OpenBLAS 
sudo chmod o+w,g+w /usr/lib64/OpenBLAS/ 
make PREFIX=/usr/lib64/OpenBLAS install 
sudo rm /etc/ld.so.conf.d/atlas-x86_64.conf 
sudo ldconfig 
sudo ln -sf /usr/lib64/OpenBLAS/lib/libopenblas.so /usr/lib64/libblas.so 
sudo ln -sf /usr/lib64/OpenBLAS/lib/libopenblas.so /usr/lib64/libblas.so.3 
sudo ln -sf /usr/lib64/OpenBLAS/lib/libopenblas.so /usr/lib64/libblas.so.3.5 
sudo ln -sf /usr/lib64/OpenBLAS/lib/libopenblas.so /usr/lib64/liblapack.so 
sudo ln -sf /usr/lib64/OpenBLAS/lib/libopenblas.so /usr/lib64/liblapack.so.3 
sudo ln -sf /usr/lib64/OpenBLAS/lib/libopenblas.so /usr/lib64/liblapack.so.3.5 
+0

I passaggi che sto eseguendo in AWS continuano a sostenere che sto eseguendo F2J. Quali altri passi hai fatto per portare brezza a questa lib nativa? Hai incluso il dep di breeze nativo? Qual è il significato di includere un class class aggiuntivo nella tua domanda? Nel tuo esempio è quello che sembrava raccogliere la lib nativa e non F2J. –