2016-06-16 37 views
23

Próbuję skonfigurować środowisko do obsługi eksploracyjnych analiz danych w klastrze. Na podstawie wstępnej ankiety dotyczącej tego, co tam jest, moim celem jest użycie Scala/Spark z Amazon EMR do obsługi klastra.Jak skonfigurować wysoką wydajność BLAS/LAPACK dla Breeze na Amazon EMR, EC2

Obecnie próbuję uzyskać kilka podstawowych przykładów, aby sprawdzić, czy wszystko jest poprawnie skonfigurowane. Problem polega na tym, że nie widzę wydajności, której oczekuję od bibliotek BLAS Atlas w instancji maszyny Amazon.

Poniżej znajduje się fragment kodu mojego prostego testu porównawczego. To tylko kwadratowa macierz mnożona, po której następuje mnożenie krótkiego tłuszczu i wysoka cienka wielokrotność, aby uzyskać małą matrycę, którą można wydrukować (chciałem mieć pewność, że Scala nie ominie żadnej części obliczeń z powodu leniwej oceny).

Używam Breeze dla bibliotek algebry liniowej i netlib-java ciągnąć w lokalnych bibliotekach rodzimych 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") 
    } 

podstawie sondażu internetowej benchmarków Czekam matrycy 3000x3000 mnożyć, aby wziąć około. 2-4s przy użyciu natywnej, zoptymalizowanej biblioteki BLAS. Po uruchomieniu na moim komputerze MacBook Air ten test porównawczy kończy się w 1.8s. Kiedy uruchomię to na EMR, kończy się to w około. 11s (przy użyciu instancji g2.2xlarge, chociaż podobne wyniki uzyskano w instancji m3.xlarge). Jako kolejną kontrolę krzyżową uruchomiłem wstępnie zbudowany EC2 AMI z BIDMach project na tym samym typie instancji EC2, g2.2xlarge, i uzyskałem 2.2s (zauważ, że benchmark GPU dla tych samych obliczeń dał 0,047 s).

W tym momencie podejrzewam, że netlib-java nie ładuje poprawnej biblioteki, ale tutaj utknąłem. Poszedłem przez README netlib-java wielu times i wydaje się, że libs ATLAS są już zainstalowane zgodnie z wymaganiami (patrz niżej)

[[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 

Poniżej podaję Pokaż 2 przykłady uruchomione benchmark na przykład Amazon EMR. Pierwsza pokazuje, kiedy natywny system BLAS podobno ładuje się poprawnie. Drugi pokazuje, kiedy natywny BLAS nie ładuje się i pakiet wraca do implementacji referencyjnej. Wygląda więc na to, że ładuje macierzysty BLAS na podstawie wiadomości i czasu. W porównaniu do uruchamiania lokalnie na moim Macu, przypadek BLAS nie działa w przybliżeniu w tym samym czasie, ale natywna obudowa BLAS działa na moim komputerze w 1.8 s w porównaniu do 15 w przypadku poniżej. Wiadomości informacyjne są takie same dla mojego komputera Mac w porównaniu do EMR (inne niż konkretne nazwy plików/plików itp.).

[[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 

W tym momencie mój najlepszy Domyślam się, że to jest rzeczywiście ładuje natywny lib, ale to się ładuje rodzajowe jeden. Jakieś sugestie, w jaki sposób mogę sprawdzić, która biblioteka współdzielona jest zbierana w czasie wykonywania? Próbowałem "ldd", ale wydaje się, że nie działa to w przypadku wysyłania iskier. A może moje oczekiwania co do Atlasa są błędne, ale wydaje się, że trudno jest uwierzyć, że AWS wstępnie zainstalowałby biblioteki, gdyby nie działały z rozsądnie konkurencyjną prędkością.

Jeśli widzisz, że biblioteki nie są poprawnie powiązane z EMR, podaj wskazówki dotyczące tego, co muszę zrobić, aby biblioteki Atlas mogły zostać pobrane przez netlib-java.

dzięki tim

+1

Could konwertowanie „follow-up” do odpowiedzi? Zapewnia przydatne informacje i jeśli nie będzie innej odpowiedzi, chciałbym przyznać nagrodę. Z góry dziękuję! –

+0

Nie mogę nawet odtworzyć pierwszego wystąpienia, w którym domyślna libra Atlas EMR jest domyślna. Czy robiłeś inne rzeczy inaczej (nie wymienione w twoim poście), które spowodowały użycie natywnej biblioteki zamiast F2jBLAS? Bez względu na to, co próbuję, wydaje mi się, że wciąż otrzymuję F2J. –

+0

Minęło dużo czasu, odkąd na to patrzyłem. Myślę, że sposób w jaki Netlib jest zintegrowany z Breeze zmienił się nieco. Ale jak pamiętam, kluczem do rozwiązania problemu było włączenie pliku .jar zawierającego biblioteki lokalne. W momencie, kiedy po raz pierwszy opublikowałem powyższe, JAR musiał zostać zawarty w sposób jawny z dodatkową zmienną ścieżki. NIE dostałem się do słoika z tłuszczem z moją aplikacją. Oto dobry wpis dotyczący konfigurowania netlib do korzystania z BLAS https://datasciencemadesimpler.wordpress.com/tag/blas/ –

Odpowiedz

10

Kontynuacja:

Mój wstępny wniosek jest taki, że libs Atlas domyślnie instalowane na przykład Amazon EMR jest po prostu powolne. Jest to generyczna kompilacja, która nie została zoptymalizowana dla określonego typu komputera, lub jest zasadniczo wolniejsza niż inne biblioteki.Korzystając z tego script jako przewodnika zbudowałem i zainstalowałem OpenBLAS dla konkretnego typu komputera, na którym prowadziłem testy porównawcze (znalazłem także pomocne informacje: here). Po zainstalowaniu OpenBLAS mój test mnożenia macierzy 3000x3000 zakończył się w 3,9 s (w porównaniu do 15.1 wymienionych powyżej przy użyciu domyślnych bibliotek Atlas). To wciąż jest wolniejsze niż ten sam test porównawczy na moim Macu (o współczynnik x2), ale ta różnica mieści się w zakresie, który może być wiarygodny z powodu podstawowej wydajności h/w.

Powyżej znajduje się pełna lista komend Kiedyś zainstalować OpenBLAS bibliotekami na Amazon EMR, Spark instancję:

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

Kroki, które mam uruchomione w AWS, nadal twierdzą, że używam F2J Jakie inne kroki podjąłeś, aby wskazać powiew do tej natywnej biblioteki? Czy dodałeś do tego depresję natywną na Breeze? Jakie jest znaczenie dodania dodatkowej klasy do twojego pytania? W twoim przykładzie zdawało się, że podnosisz rodzimą bibliotekę, a nie F2J. –