【Python筆記】如何編譯不依賴lapack和atlas庫的NumPy包

NumPy是科學計算方面的一個Python庫,在數據挖掘或機器學習或科學統計等領域經常被用到,官網在這裏
在實際業務中,爲發揮NumPy的高性能,在編譯NumPy時會依賴一些經過特別優化的第三方科學計算庫。對於初次接觸NumPy的新手來說,從源碼編譯安裝依賴外部庫的NumPy通常不是一個簡單的任務
事實上,NumPy這個Python包本身不需依賴任何第三方庫就能完成編譯和安裝使用只不過其計算性能會受到影響
本篇筆記記錄的是如何在不依賴外部庫的情況下來編譯使用NumPy,這樣做爲了理清NumPy與第三方庫的關係(相信很多NumPy初學者會分不清NumPy和幾個生僻第三方庫的關係,以爲沒有第三方庫就不能編譯使用NumPy)。

備註1:下面關於NumPy包的安裝過程是藉助virtualenv在一個隔離的Python環境下實驗的,所以,假定我們已經通過"virtualenv numpy-env"命令創建並通過activate操作進入了隔離環境。
備註2:本篇筆記用到的gcc版本是gcc version 3.4.5,很舊的版本,不過依然可以編譯最新版的NumPy v1.9.2。

1. 高性能NumPy包通常會依賴LAPACK和ATLAS庫
lapack和atlas是科學計算領域的兩個針對線性代數運算的經過特別優化的非常強大的工具庫,關於它們的說明,可以分別查看lapack官網atlas官網的說明。
經常與這兩個庫一起出現的還有個BLAS庫,其官網在這裏
關於這3個庫之間的關係,可以參考StackOverflow的這篇問答貼What is the relation between BLAS, LAPACK and ATLAS

2. 如何不依賴第三方計算庫編譯NumPy
根據NumPy官方文檔Building and installing NumPy在Building from source部分關於Linear Algebra libraries的說明,這兩個庫對於安裝NumPy包來說並不是強制依賴的。
下面就是不依賴lapack和atlas庫的情況下,源碼編譯/安裝NumPy包的步驟。
從官網下載NumPy源碼(以最新版numpy-1.9.2.tar.gz爲例),解壓並cd至解壓目錄後,可以通過下面的方法安裝未經優化的NumPy庫:
$ export BLAS=None
$ export LAPACK=None
$ export ATLAS=None
$ python setup.py build > bld.log
$ python setup.py install
編譯/安裝完成後,可以這樣來驗證:
>>> import numpy
>>> numpy.__version__
'1.9.2'
複雜點的例子:
>>> import numpy as np        
>>> from numpy.linalg import *
>>> 
>>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> print a
[[ 1.  2.]
 [ 3.  4.]]
>>> a.transpose()
array([[ 1.,  3.],
       [ 2.,  4.]])
>>> inv(a)
array([[-2. ,  1. ],
       [ 1.5, -0.5]])
可見,不依賴任何第三方計算庫的NumPy確實是可以正常使用的。

3. 不依賴第三方計算庫對NumPy有何影響
目前爲止,雖然確實成功編譯並能正常使用NumPy,但仔細查看編譯過程輸出的bld.log日誌文件,可以發現這樣一段提示:

building extension "numpy.linalg.lapack_lite" sources
creating build/src.linux-x86_64-2.7/numpy/linalg
### Warning:  Using unoptimized lapack ###
  adding 'numpy/linalg/lapack_litemodule.c' to sources.
  adding 'numpy/linalg/lapack_lite/python_xerbla.c' to sources.
  adding 'numpy/linalg/lapack_lite/zlapack_lite.c' to sources.
  adding 'numpy/linalg/lapack_lite/dlapack_lite.c' to sources.
  adding 'numpy/linalg/lapack_lite/blas_lite.c' to sources.
  adding 'numpy/linalg/lapack_lite/dlamch.c' to sources.
  adding 'numpy/linalg/lapack_lite/f2c_lite.c' to sources.
building extension "numpy.linalg._umath_linalg" sources
### Warning:  Using unoptimized lapack ###
  adding 'numpy/linalg/umath_linalg.c.src' to sources.
  adding 'numpy/linalg/lapack_lite/python_xerbla.c' to sources.
  adding 'numpy/linalg/lapack_lite/zlapack_lite.c' to sources.
  adding 'numpy/linalg/lapack_lite/dlapack_lite.c' to sources.
  adding 'numpy/linalg/lapack_lite/blas_lite.c' to sources.
  adding 'numpy/linalg/lapack_lite/dlamch.c' to sources.
  adding 'numpy/linalg/lapack_lite/f2c_lite.c' to sources.
conv_template:> build/src.linux-x86_64-2.7/numpy/linalg/umath_linalg.c
其中,"Warning:  Using unoptimized lapack"表明編譯numpy相關的線性代數庫(linalg)時,所依賴的lapack函數庫是NumPy源碼自帶的一份未經優化的實現。
幾點說明如下:
1) 查看numpy-1.9.2/numpy/linalg目錄下的源碼可看到,lapack_litemodule.c文件是NumPy爲Python實現的C語言擴展庫的“接口”文件,該文件定義了一系列Python與C交互的接口函數。寫過Python C擴展的話,應該很容易就能看出來,這裏不贅
2) linalg/lapack_lite目錄下的幾個C文件是NumPy自帶的未經優化的線性代數算法的實現文件
3) 安裝前將BLAS/LAPACK/ATLAS幾個環境變量export爲None後,NumPy的setup腳本就不會嘗試在其它路徑下搜索這幾個庫的優化版本,此時,編譯腳本會用自帶的linalg/lapack_lite目錄下的未優化實現編譯出動態庫lapack_lite.so供上層的Python應用程序調用

總之,NumPy是否依賴lapack和atlas庫,主要影響的是其性能,其功能不受影響
另外,在實際開發環境中,用到Numpy的地方通常也會用到SciPy,而SciPy是必須依賴lapack和atlas庫的,所以,實際項目中使用的NumPy庫通常會依賴lapack和atlas。
而從源碼編譯依賴lapack和atlas庫的numpy庫通常需要一些注意事項,下篇筆記將會給出說明。

【參考資料】
1. NumPy官網 
2. LAPACK官網
3. ATLAS官網 
4. BLAS官網 
5. StackOverflow - What is the relation between BLAS, LAPACK and ATLAS  
6. Building and installing NumPy  
7. SciPy.org - Building From Source on Linux 

====================== EOF ======================


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章