Apache spark 如何在Amazon EMR、EC2上为Breeze配置高性能BLAS/LAPACK

Apache spark 如何在Amazon EMR、EC2上为Breeze配置高性能BLAS/LAPACK,apache-spark,amazon-ec2,amazon-emr,scala-breeze,jblas,Apache Spark,Amazon Ec2,Amazon Emr,Scala Breeze,Jblas,我正在尝试建立一个环境来支持集群上的探索性数据分析。根据对现有内容的初步调查,我的目标是使用Scala/Spark和Amazon EMR来提供集群 目前,我正在尝试建立一些基本的示例并运行,以验证我是否已正确配置了所有内容。我遇到的问题是,我没有看到Amazon机器实例上Atlas BLAS库的预期性能 下面是我的简单基准测试的代码片段。它只是一个平方矩阵乘法,然后是短胖乘法和高瘦乘法,以生成一个可以打印的小矩阵(我想确保Scala不会因为延迟计算而跳过计算的任何部分) 我正在为线性代数库和ne

我正在尝试建立一个环境来支持集群上的探索性数据分析。根据对现有内容的初步调查,我的目标是使用Scala/Spark和Amazon EMR来提供集群

目前,我正在尝试建立一些基本的示例并运行,以验证我是否已正确配置了所有内容。我遇到的问题是,我没有看到Amazon机器实例上Atlas BLAS库的预期性能

下面是我的简单基准测试的代码片段。它只是一个平方矩阵乘法,然后是短胖乘法和高瘦乘法,以生成一个可以打印的小矩阵(我想确保Scala不会因为延迟计算而跳过计算的任何部分)

我正在为线性代数库和netlib java使用Breeze来为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")
  }
基于对基准测试的网络调查,我预计使用本机优化的BLAS库,3000x3000矩阵乘法大约需要2-4s。当我在MacBook Air上本地运行时,这个基准测试在1.8秒内完成。当我在EMR上运行此程序时,大约需要11秒(使用g2.2xlarge实例,但在m3.xlarge实例上也获得了类似的结果)。作为另一个交叉检查,我在相同的EC2实例类型g2.2xlarge上运行了一个来自的预构建EC2 AMI,得到了2.2s(注意,相同计算的GPU基准得到了0.047s)

在这一点上,我怀疑netlibjava没有加载正确的lib,但这就是我遇到的问题。我已经阅读了很多netlib java自述文件,ATLAS LIB似乎已经按要求安装(见下文)

下面我展示了在AmazonEMR实例上运行基准测试的两个示例。第一个显示本机系统BLAS假定正确加载的时间。第二个显示本机BLAS未加载且包返回到引用实现时的情况。因此,它似乎正在根据消息和时间加载本机BLAS。与在我的Mac上本地运行相比,无BLAS案例的运行时间大致相同,但本机BLAS案例在我的Mac上的运行时间为1.8秒,而在下面的案例中为15秒。与EMR相比,my Mac的信息消息是相同的(除了特定的目录/文件名等)

[hadoop@ip-172-31-3-69~]$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-dependenciences.jar 3000朴素
向量长度为3000的朴素多重通信
2016年6月16日上午12:30:39 com.github.fommil.jni.JniLoader liberalLoad
信息:已成功加载/tmp/jniloader285601049061057802netlib-native_system-linux-x86_64.so
com.github.fommil.netlib.NativeSystemBLAS
a和b的点积是
1.677332076284315E9 1.6768329748988206E9 1.692156424957E9
1.699900993276503E9 1.6993872020220244E9 1.7149145239563465E9
运行时间:15.1s
[hadoop@ip-172-31-3-69 ~]$ 
[hadoop@ip-172-31-3-69~]$spark提交--“com.cyberatomics.simplespark.App”类--master local[4]simplespark-0.0.1-SNAPSHOT-jar-with-dependencies.jar 3000 naive
向量长度为3000的朴素多重通信
2016年6月16日12:31:32 AM com.github.fommil.netlib.BLAS
警告:未能从以下位置加载实现:com.github.fommil.netlib.NativeSystemBLAS
2016年6月16日12:31:32 AM com.github.fommil.netlib.BLAS
警告:未能从以下位置加载实现:com.github.fommil.netlib.NativeRefBLAS
com.github.fommil.netlib.F2jBLAS
a和b的点积是
1.6640545115052865E9 1.6814609592621212E9 1.7062846398842275E9
1.64471099826913E9 1.6619129531594608E9 1.6864479674870768E9
运行时间:28.7秒
在这一点上,我最好的猜测是它实际上正在加载一个本机库,但它正在加载一个通用库。关于如何验证它在运行时接收的共享库,有什么建议吗?我尝试了“ldd”,但这似乎对spark submit不起作用。或许我对Atlas的期望是错误的,但似乎很难相信AWS会在运行速度不具备合理竞争力的情况下预装libs

如果您看到没有在EMR上正确连接库,请提供关于我需要做什么的指导,以便netlib java获取Atlas库

谢谢 tim

跟进:

我的初步结论是,默认情况下安装在AmazonEMR实例上的AtlasLibs非常慢。要么它是一个没有针对特定机器类型进行优化的通用构建,要么它从根本上比其他库要慢。以此为指导,我为运行基准测试的特定机器类型构建并安装了OpenBLAS(我还发现了一些有用的信息)。安装OpenBLAS后,我的3000x3000矩阵乘法基准测试用3.9秒完成(与使用默认Atlas libs时的15.1秒相比)。这仍然比在我的Mac电脑上运行的同一个基准测试慢(x2倍),但这种差异落在一个可信的范围内,这可能是由于潜在的h/w性能造成的

下面是我在Amazon的EMR Spark实例上安装OpenBLAS libs时使用的命令的完整列表:

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

你能把“跟进”转换成一个答案吗?它提供了有用的见解,如果没有任何其他答案,我想奖励赏金。提前谢谢!我甚至无法重新创建您拉入默认EMR Atlas本机库的第一个实例。您是否做了其他不同的事情(未在您的帖子中列出),导致使用本机lib而不是F2jBLAS?不管我怎么做,我似乎还是得到了F2J。我已经很久没有看到这个了。我认为netlib与Breeze集成的方式已经发生了一些变化。但我记得,解决问题的关键是包含包含本机库的.jar
[hadoop@ip-172-31-3-69 ~]$ 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
[hadoop@ip-172-31-3-69 ~]$ 
[hadoop@ip-172-31-3-69 ~]$ 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
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