【问题标题】:How to configure high performance BLAS/LAPACK for Breeze on Amazon EMR, EC2如何在 Amazon EMR、EC2 上为 Breeze 配置高性能 BLAS/LAPACK
【发布时间】:2016-10-17 07:45:09
【问题描述】:

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

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

下面是我的简单基准测试的代码 sn-p。它只是一个方形矩阵乘法,然后是一个短粗乘法和一个高细乘法,以产生一个可以打印的小矩阵(我想确保 Scala 不会因为惰性求值而跳过任何计算部分)。

我将 Breeze 用于线性代数库,并使用 netlib-java 为 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")
  }

基于对基准的网络调查,我预计 3000x3000 矩阵乘法大约需要 3000x3000 矩阵。 2-4s 使用本地优化的 BLAS 库。当我在我的 MacBook Air 上本地运行时,这个基准测试在 1.8 秒内完成。当我在 EMR 上运行它时,它大约会完成。 11s(使用 g2.2xlarge 实例,尽管在 m3.xlarge 实例上获得了类似的结果)。作为另一项交叉检查,我在相同的 EC2 实例类型 g2.2xlarge 上从 BIDMach project 运行了一个预构建的 EC2 AMI,并得到了 2.2 秒(注意,相同计算的 GPU 基准测试产生了 0.047 秒)。

此时我怀疑 netlib-java 没有加载正确的库,但这就是我卡住的地方。我已经阅读了许多times 的 netlib-java 自述文件,似乎 ATLAS 库已按要求安装(见下文)

[hadoop@ip-172-31-3-69 ~]$ 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
[hadoop@ip-172-31-3-69 ~]$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
[hadoop@ip-172-31-3-69 ~]$ 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
[hadoop@ip-172-31-3-69 ~]$ cat /etc/ld.so.conf.d/atlas-x86_64.conf 
/usr/lib64/atlas

下面我展示了在 Amazon EMR 实例上运行基准测试的 2 个示例。第一个显示本机系统 BLAS 应该正确加载的时间。第二个显示当本机 BLAS 未加载并且包回退到参考实现时。因此,它似乎确实在根据消息和时间加载本机 BLAS。与在我的 Mac 上本地运行相比,no BLAS 案例的运行时间大致相同,但本机 BLAS 案例在我的 Mac 上的运行时间为 1.8 秒,而在下面的案例中为 15 秒。与 EMR 相比,我的 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-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

在这一点上,我最好的猜测是它实际上是在加载一个本机库,但它正在加载一个通用库。关于如何验证它在运行时拾取的共享库有什么建议吗?我试过'ldd',但这似乎不适用于spark-submit。或者也许我对 Atlas 的期望是错误的,但如果它们的运行速度不合理,似乎很难相信 AWS 会预先安装这些库。

如果您发现这些库未在 EMR 上正确链接,请提供有关我需要执行哪些操作以使 netlib-java 获取 Atlas 库的指导。

谢谢 时间

【问题讨论】:

  • 你能把“跟进”转换成答案吗?它提供了有用的见解,如果没有其他答案,我想奖励赏金。提前致谢!
  • 我什至无法重新创建您拉入默认 EMR Atlas 原生库的第一个实例。您是否做了其他不同的事情(未在您的帖子中列出)导致使用本机库而不是 F2jBLAS?无论我尝试什么,我似乎仍然在获得 F2J。
  • 很久没看这个了。我认为 netlib 与 Breeze 集成的方式发生了一些变化。但我记得,解决问题的关键是包含包含本机库存根的 .jar。在我第一次发布上述内容时,该 jar 必须明确包含一个附加路径变量。它没有包含在我的应用程序的胖罐中。这是一篇关于设置 netlib 以使用 BLAS datasciencemadesimpler.wordpress.com/tag/blas 的好帖子
  • 是的,我终于能够从上面和我发现的其他一些随机线程中弄清楚这一点。您的帖子和回答对我的过程非常有帮助,不胜感激!

标签: apache-spark amazon-ec2 amazon-emr scala-breeze jblas


【解决方案1】:

跟进:

我的初步结论是,默认安装在 Amazon EMR 实例上的 Atlas 库很慢。它要么是没有针对特定机器类型优化的通用构建,要么从根本上比其他库慢。使用此script 作为指南,我为运行基准测试的特定机器类型构建并安装了 OpenBLAS(我还发现了一些有用的信息here)。安装 OpenBLAS 后,我的 3000x3000 矩阵乘法基准测试在 3.9 秒内完成(与上面列出的使用默认 Atlas 库时的 15.1 秒相比)。这仍然比在我的 Mac 上运行的相同基准测试慢(x2 倍),但这种差异落在一个可能是由于潜在的硬件性能而令人信服的范围内。

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

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

【讨论】:

  • 我在 AWS 中运行的步骤仍然声称我在运行 F2J。你还采取了哪些其他步骤来将微风指向这个原生库?你是否包含了微风原生的 dep?包含的意义是什么您的问题中有一个额外的 classPath?在您的示例中,这似乎是选择了本机库而不是 F2J。
猜你喜欢
  • 2018-07-27
  • 1970-01-01
  • 2018-05-21
  • 2012-12-31
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 2019-02-12
  • 2018-03-04
相关资源
最近更新 更多