【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 ======================

时间: 2024-08-05 08:35:11

【Python笔记】如何编译不依赖lapack和atlas库的NumPy包的相关文章

【Python笔记】如何源码编译依赖LAPACK和ATLAS库的NumPy包

上篇笔记介绍了不依赖lapack和atlas库的NumPy包源码编译/安装方法,但"纯净版"的NumPy会损失性能,故本篇笔记说明如何源码编译安装依赖lapack和atlas库的NumPy包. 1. GCC版本要求 使用较新版本的GCC工具集(尽量不低于v4.7)且集成有gfortran编译器. 备注1:这里大写的"GCC"是指GNU Compiler Collection,它除包含C语言编译器gcc外,还包含很多其它语言的编译器(如g++/gfortran等) 备

Python笔记之不可不知

Python软件已经安装成功有很长一段时间了,也即或多或少的了解Python似乎也很长时间了,也是偏于各种借口,才在现在开始写点总结.起初接触Python是因为公司项目中需要利用Python来测试开发的接口,于是开始了解这门解释性,面向对象,带有动态语义的高级语言,或是脚本语言,或是胶水语言.便在网上找了一个现成的Python爬虫,在本地测试运行成功,将新浪上面的所有博客地址扒取下来.真心想从基础学起,自己写个,于是,有了这份基础总结,项目模块的开发将在下一篇博文中贴出.敬请关注! 本博文仅记录

Maven学习笔记之——坐标和依赖(上)

Maven学习笔记之--坐标和依赖(上) 1.    Maven坐标概念 Maven通过构件的坐标来在Maven仓库中定位到具体的构件.Maven的坐标元素包括groupId.artifactId.versiion.packaging.classifier.Maven内置了一个中央仓库地址.需要时Maven会根据坐标到其中下载.具体关于中央仓库的介绍在后面. 2.    Maven坐标详解 比如下面一组坐标: <groupId>org.andy.items</groupId> &l

智普教育Python视频教程之入门基础篇,python笔记

智普教育Python视频教程之入门基础篇,python笔记 print id()内存地址 type()变量类型 windows命令行下edit命令 python数据类型不需要指定类型 定义hostname="www.google.com" 结果运行后总是告诉我NameError: name 'socket' is not defined 哪位帮我分析一下,怎么改才对 没用过socket,不过你试着在第一行加入 import socket C:\>notepad somefile.

maven依赖本地非repository中的jar包-依赖jar包放在WEB-INF/lib等目录下的情况客户端编译出错的处理

maven依赖本地非repository中的jar包 http://www.cnblogs.com/piaolingxue/archive/2011/10/12/2208871.html 博客分类: MAVEN 今天在使用maven编译打包一个web应用的时候,碰到一个问题: 项目在开发是引入了依赖jar包,放在了WEB-INF/lib目录下,并通过buildpath中将web libariary导入. 在eclipse中开发没有问题,但是使用maven编译插件开始便宜总是报找不到WEB-INF

Python笔记_01列表 和元祖

Python笔记 第一章 列表和元祖 1.通用序列操作 所有序列都可以进行某些特定操作,包括:索引(indexing).分片(slicing).加(adding).乘(multiplying)以及检查某元素是否属于列表成员. 迭代:依次对序列中的每个元素重复执行某些操作. 序列的索引:通过元素在列表中的位置可以定位到该元素,这就是列表的索引,使用类似于list[0]对元素进行索引,索引0指向第一个元素.也可使用负数对元素进行索引,使用负数对元素索引时,列表中的最后一个元素由-1表示,例如list

(转)redis 学习笔记(1)-编译、启动、停止

redis 学习笔记(1)-编译.启动.停止 一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先到这里下载Stable稳定版,目前最新版本是2.8.17 1.2 上传到linux,然后运行以下命令解压 tar xzf redis-2.8.17.tar.gz 1.3 编译 cd redis-2.8.17make 注:make命令需要linux上安装gcc,若机器上未安装gcc,redhat环境下,如

DuiLib学习笔记1——编译运行demo

c++中皮肤问题比较麻烦,MFC自带的太难用.DirectUI界面库就比较强大了,之前像skin++之类的基于DirectUI收费昂贵.DuiLib是基于DirectUI的界面库,可以将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率. duilib的SVN地址:http://duilib.googlecode.com/svn/trunk 下载后运行DuiLib.sln 编译时可能会遇到几个报错. 0.开发环境本身有问题,比如用win7没有装win7sdk之类的. 1. TestApp1

玩蛇(Python)笔记之基础Part3

玩蛇(Python)笔记之基础Part1 一.集合 1.set 无序,不重复序列 {}创建,直接写元素 2.set功能 __init__()构造方法,,使用强制转换就会调用此方法 1 set1 = {'year', 'jiujiujiu'} 2 print(type(set1)) 3 # 创建集合 4 s = set() # 创建空集合 5 li = [11, 22, 11, 22] 6 s = set(li) set 3.集合的基本操作 1 # 操作集合 2 s1 = set() 3 s1.a