Ich versuche, eine Umgebung zur Unterstützung der explorativen Datenanalyse in einem Cluster einzurichten. Basierend auf einer ersten Umfrage, was mein Ziel ist, verwende ich Scala/Spark mit Amazon EMR, um den Cluster bereitzustellen.So konfigurieren Sie Hochleistungs-BLAS/LAPACK für Breeze auf Amazon EMR, EC2
Momentan versuche ich nur ein paar grundlegende Beispiele zu bekommen, um zu bestätigen, dass ich alles richtig konfiguriert habe. Das Problem, das ich habe, ist, dass ich nicht die Leistung sehe, die ich von den Atlas BLAS-Bibliotheken auf der Amazon-Maschineninstanz erwarte.
Unten ist ein Codeausschnitt meines einfachen Benchmarks. Es ist nur eine quadratische Matrix multiply, gefolgt von einer kurzen fetten Multiplikation und einer hohen dünnen Multiplikation, um eine kleine Matrix zu erhalten, die gedruckt werden kann (ich wollte sicher sein, dass Scala keinen Teil der Berechnung wegen einer faulen Auswertung überspringen würde).
Ich verwende Breeze für die lineare Algebra Bibliothek und netlib-java in den lokalen nativen Bibliotheken für 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")
}
Basierend auf einer Web-Umfrage von Benchmarks eine 3000x3000 zu ziehen Matrix Ich erwarte multiplizieren, um ca. 2-4s mit einer nativen, optimierten BLAS-Bibliothek. Wenn ich lokal auf meinem MacBook Air laufe, ist dieser Benchmark in 1,8 Sekunden abgeschlossen. Wenn ich dies auf EMR ausführe, ist es in ca. abgeschlossen. 11s (mit einer g2.2xlarge-Instanz, obwohl ähnliche Ergebnisse auf einer 3.x3-Instanz erhalten wurden). Als weiteren Vergleichstest habe ich einen vorgefertigten EC2 AMI von BIDMach project auf dem gleichen EC2-Instance-Typ, g2.2xlarge, ausgeführt und 2.2s erhalten (beachten Sie, dass der GPU-Benchmark für die gleiche Berechnung 0.047s ergab).
An dieser Stelle vermute ich, dass netlib-java nicht die richtige lib lädt, aber das ist, wo ich feststecke. Ich habe durch die netlib-java README viele gegangen times und es scheint, dass die ATLAS-Libs sind bereits nach Bedarf installiert (siehe unten)
[[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
Unten habe ich zeigen zwei Beispiele, um die Benchmark auf Amazon EMR-Instanz läuft. Die erste zeigt, wenn das native System BLAS angeblich korrekt lädt. Die zweite zeigt, wenn das native BLAS nicht geladen wird und das Paket auf die Referenzimplementierung zurückfällt. Es scheint also, ein natives BLAS basierend auf den Nachrichten und dem Timing zu laden. Verglichen mit der lokalen Ausführung auf meinem Mac läuft der no BLAS-Fall ungefähr zur gleichen Zeit, aber der native BLAS-Fall läuft in 1.8s auf meinem Mac, verglichen mit 15s in dem Fall unten. Die Info-Nachrichten sind für meinen Mac im Vergleich zu EMR dieselben (abgesehen von bestimmten Verzeichnis-/Dateinamen usw.).
[[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
An dieser Stelle meine beste Vermutung ist, dass es tatsächlich eine native lib wird geladen, aber es ist ein generisches ein Laden. Irgendwelche Vorschläge, wie ich überprüfen kann, welche gemeinsame Bibliothek zur Laufzeit abgerufen wird? Ich habe 'ldd' ausprobiert, aber das scheint nicht mit Funkensummen zu funktionieren. Oder vielleicht sind meine Erwartungen für Atlas falsch, aber es scheint schwer zu glauben, dass AWS die Bibliotheken vorinstallieren würde, wenn sie nicht mit einigermaßen wettbewerbsfähigen Geschwindigkeiten arbeiten würden.
Wenn Sie sehen, dass die Bibliotheken nicht korrekt mit EMR verbunden sind, geben Sie bitte an, was zu tun ist, damit die Atlas-Bibliotheken von netlib-java abgeholt werden können.
dank tim
Könnten Sie konvertieren „follow-up“ in eine Antwort? Es liefert nützliche Einsichten und wenn es keine andere Antwort gibt, würde ich gerne das Kopfgeld vergeben. Danke im Voraus! –
Ich kann nicht einmal die erste Instanz neu erstellen, wo Sie die standardmäßige EMR Atlas native lib abrufen. Haben Sie andere Dinge anders gemacht (nicht in Ihrem Beitrag aufgelistet), die dazu führten, dass die native lib anstelle von F2jBLAS verwendet wurde? Egal was ich versuche, ich scheine immer noch F2J zu bekommen. –
Es ist lange her, dass ich mir das anschaue. Ich denke, die Art, wie Netlib in Breeze integriert ist, hat sich ein wenig verändert. Aber soweit ich mich erinnere, war der Schlüssel, um über Ihr Problem hinwegzukommen, die .jar-Datei, die die nativen Bibliotheks-Stubs enthält. Zu der Zeit, als ich das oben Gesagte zum ersten Mal veröffentlichte, musste das Jar HAD explizit mit einer zusätzlichen Pfadvariablen eingeschlossen werden. Es wurde NICHT in das Fettglas mit meiner Anwendung aufgenommen. Hier war ein guter Beitrag zum Einrichten von netlib, um BLAS zu verwenden https://datasciencemadesimpler.wordpress.com/tag/blas/ –