给作者编号

给作者编号

Author Number

http://zhanxw.com/author

 

最近写了一个网页,主要解决写文章给作者编号的问题。这个问题怎么来的呢?现在的文章需要提供作者,作者工作单位和作者的贡献,但是提供的方式是给每个作者单位按照作者出现的顺序编号。比如我的文章有79个作者,现在突然要加一个新的合作者,把他拍到第50位,那么从第51位到最后一位作者的编号可能都需要改变。这个过程很容易出错。我想写个软件给所有人用,顺便凑个热闹,学习一下jQuery + Django,最后的作品放到我的网页(link)。在这个过程中,还学习了Nginx, Emacs web-mode, 这篇笔记主要是把我的经验记录下来。

 

1. 学习Django

Django是Python语言实现的Web架构,它最开始是用于展示新闻(Newroom),国内的豆瓣也用Django。作为Python的“粉丝”,我学一下Django,希望以后可以把有用的工具放到网上。

想入门,最好最省时间的方法是Django tutorial,就在Django的官方网页。这个Tutorial一共有六个部分,介绍的常用Django的功能,包括: 模型(Model),模板(Template),视图(View),静态文件(Static),管理界面(Admin),网址分发(URL Dispatching)等等。学习之后,我感到Django的强项是利用Python语言做到来简化数据库使用。对于一个简单的App,基本开发的流程是: (1)设定project 的settings.py 和urls.py,注册新的app ;(2)设定urls.py来确定网址和视图(View)的关系;(3)用HTML开发模板(/template/app/XXX.html)同时实现各种需要的视图(views.py)

架设Django,一般简易使用uWSGI。我使用的是Nginx处理静态页面,同时用uWSGI处理Django相关界面。简易先在本机用uWSGI调好程序,再放到服务器上并配置Nginx和uWSGI。

Djano默认使用Unicode,而我们一般都用str(),这是ASCII编码。两种编码对于字符串处理来讲(包括join, index)没有什么区别,但在print的时候,Unicode的字符应该先转成UTF-8字符,比如: print u”aaa”.encode(‘UTF-8’)

 

2. 学习jQuery

用jQuery的主要目的是用Ajax来更新网页数据,这样用户用起来有行云流水的感觉。jQuery有.get 和 .post两个方法,使用起来和访问网页很相似。不过这里面有几个陷阱。第一个是GET方式适合小数据,对于Django来讲,默认的大小是4096个字符,大一点的数据应该用POST;第二个陷阱就是POST,为了安全(CSRF: cross-site request forgery),Django要求POST的数据必须有csrftoken,一般的HTML表格Form必须有csrf的标记才会被Django接收。

为了调试Ajax的输入输出,简易用Firefox下的FireBug或者最新版本的Firefox,它们都可以显示Ajax请求的参数和返回值。最新版本的Firefox还可以给Javascript设置断点,这就更加降低了调试的难度。

jQuery的功能很多,这个网页把jQuery 1.9以及之前版本的功能用不同颜色区分出来,很方便查询(link)。

在这个网页中,我还用了handsontable,这是一个在jQuery的基础上开发的实用的javascript spreadsheet,语法简单,使用方便。

3. 一点Nginx经验

对Nginx来讲,我们的配置是用location语句来把特定的网址传给uWSGI进程。注意Nginx设置里如果有多个location语句,Nginx并不一定选择最先匹配的网址,而是选择最长的网址。比如:

location ~* /author/static/.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
root /var/django/zhanxw/; # STATIC_ROOT
expires 30d;
}

location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
access_log        off;
expires           30d;
root /var/www;
}

如果第一个location写成: “location /author/static”,那么.jpg之类的文件会被第二个location处理,这就不是Django static文件的正确处理方式。

 

4. 一点Emacs web-mode经验

用Emacs写Django的模板HTML,最好用的不是django-html-mode,而是web-mode。只有这个mode可以识别 “{% static ‘polls/index.html’ %}”这样的记号,并正确缩进。

此外web-mode可以自动补全HTML tab,比如你在<p>后面打</,web-mode会帮你补全</p>。还可以用C-c C-e b 和C-c C-e e跳到一对tag的最前面(beginning)和最后面(end)。

 

5. 一般性经验

最开始设计应该以最少功能,最小实现为好,不要一下子把界面设计复杂。可以想几个用例(Use Case),保证最基本最重要的功能,其他功能应该越少越好。

网页的布局应该少用<br/>这种硬回车。在有Bootstrap的情况下,完全可以用<div>和<p>来用更少的HTML tag来实现更自然、自动的布局。

 

让R更快

让R更快
Speed up R

用R 3.0.1来做基准,用Rscript运行R-benchmark-25.R计时。

1) 基准时间:

197.16u 1.74s 199.71r 1703184kB 0 Rscript R-benchmark-25.R

之后下载OpenBLAS,编译,然后把编译好的libopenblas.so 替换R自带的libRblas.so.
2) 测试单线程的速度:

Single thread OpenBLAS

105.83u 108.53s 58.04r 3072256kB 0 Rscript R-benchmark-25.R

 

3) 下面试试四个线程:

Four threaded OpenBLAS

export OPENBLAS_NUM_THREADS=4

79.39u 23.67s 58.54r 2122688kB 0 Rscript R-benchmark-25.R
可以看出使用四个线程和一个线程耗时差不多一样。但如果细看矩阵计算时间(这里忽略),四个线程还是能提速不少的。
但是考虑到使用方便,一个线程在大多数情况下应该就够用了。

用pip安装Matplotlib (Mac)

Install matplotlib using pip (Mac)

在Mac OSX下安装matplotlib并不简单 (比如Linux可以用apt-get,Windows可以直接下载Binary build),因为matplotlib需要一些底层库(例如freetype,pygtk,而pygtk又需要gobject, gobject需要cairo)。

这里总结一下我在Mac OSX下安装Matplotlib的经验。

首先安装MacPorts,具体参见Install MacPorts.

然后安装py27-pygtk

 port install py27-pygtk

然后把pygtk的路径添加到PYTHONPATH里:

export PYTHONPATH=$PYTHONPATH:/opt/local//Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/

最后用pip安装

alias pipInstall='pip install  --install-option="--prefix=/Users/zhanxw/python" '
export CC=/opt/local/bin/g++; export CFLAGS=; export LDFLAGS= ; pipInstall -U matplotlib

这里要指定GCC编译器的路径,否则系统默认用gcc 4.2版编译。
还需要清除CFLAG和LDFLAGS,不然安装的时候不用pkg-config,也就得不到gtk库文件的位置。

额外两个tip:

【1】 安装pip需要先安装setuptools
【2】 一个命令升级所有pip安装的软件:

  pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs pip install -U

此外如何在Mac OSX下用源码安装numpy和scipy?
这里有官网的说明
特别注意的是,编译numpy和scipy要用gcc 4.0版。
另外scipy还需要cython (pip install cython)

在Solaris下安装R

2015-06-16 更新:
这里讲的方法可能已经不管用了,至少在我使用Solaris 10 的VirtualBox Image的时候,下面的方法行不通。

Install Solaris 10 and install R under Solaris
最近的写的一个R package vcf2geno不能在Solaris 10 下编译。
为了解决这个问题,我决定重复CRAN上Solaris 10的测试环境
下面写个流水账

1.安装Virtual Box
下载,安装。

2.安装Solaris 10 和 Guest OS
一定要注意的是手动分区,把/tmp的容量设置到5G以上。不然默认的/tmp只有512M,这样就不方便安装Solaris Studio (第3步)。
安装virtualBox的Guest OS 软件后,Solaris的屏幕分辨率增加。

3.安装Solaris Studio 12.3
下载,解压,安装 (就是特别慢)

4.安装OpenSolaris
Solaris里面没有ubuntu的apt和fedora的yum,但是有个类似的软件叫做OpenCSW Link.
参考OpenCSW的手册Getting Start.
然后用pkgutil安装tetex, gcc4g++, iconv, readline

5.下载R
去R的主页下载源代码,然后解压

6.配置环境参数,安装

export CC=suncc
export CFLAGS="-xO5 -xc99 -xlibmil -nofstore"
export CPICFLAGS=-Kpic
export F77=sunf95
export FFLAGS="-O5 -libmil -nofstore"
export FPICFLAGS=-Kpic
export CXX="sunCC -library=stlport4"
export CXXFLAGS="-xO5 -xlibmil -nofstore -features=tmplrefstatic"
export CXXPICFLAGS=-Kpic
export FC=sunf95
export FCFLAGS=$FFLAGS
export FCPICFLAGS=-Kpic
export LDFLAGS=-L/opt/sunstudio12.1/rtlibs/amd64
export SHLIB_LDFLAGS=-shared
export SHLIB_CXXLDFLAGS=-G
export SHLIB_FCLDFLAGS=-G
export SAFE_FFLAGS="-O5 -libmil"

export CPPFLAGS=’-I/opt/csw/include -I/opt/csw/include/readline’
export LDFLAGS=’-L/opt/sunstudio12.1/rtlibs/amd64 -L/opt/csw/lib’

export PATH=/usr/xpg4/bin:$PATH
export PATH=/usr/sfw/bin/:$PATH

之后我们依次执行:
./configure
gmake #(Solaris下面的GNU make)
gmake install

经验:

    Solaris下自带的软件很少,常用软件要到OpenCSW下载
    Solaris的路径设置和Linux很不同,不在/usr/bin, /usr/local/bin等等。这时候可以用glocate来快速查找, 见【2】

主要参考:
【1】http://cran.r-project.org/doc/manuals/R-admin.html#Solaris
【2】Solaris下的locate工具. Link
【3】http://www.opencsw.org/get-it/packages/

Mac Mail 邮件签名的字体

Mac Mail设置邮件签名的时候,签名字体和邮件正文总是无法一致。
比如下图:(之前)

参考:http://apple.stackexchange.com/questions/10530/mail-signature-changes-font-size-when-sent-to-gmail
发现Mac下解决这个问题不难,但也很烦。
把步骤写下来,以备不时之需吧。
1. 退出Mail
2. 进入: ~/Library/Mail/Signatures
3. 用Web Archive Folderizer打开: DBA028E6-8465-492D-B0AF-4B19D3C06450.webarchive (总之是一个奇怪的文件名字)
之后会出现新目录“DBA028E6-8465-492D-B0AF-4B19D3C06450”,里面有一个叫做“localhost”的文件。
4. 用Text Edit打开这个文件,把所有font-size = medium,都改成font-size = 12px 。 因为默认的邮件字体是Helvetica 12。
5. 把改好的文件存为localhost.html
6. 用Safari打开localhost.html,然后存成Webarchive格式,覆盖:DBA028E6-8465-492D-B0AF-4B19D3C06450.webarchive
7. 打开Mail

好了,现在的签名字体和邮件正文的字体一致了。

(之后)

iTerm2和Emacs的Meta Key

How to set up Meta appropriately for iTerm2

学校的电脑是Mac,Mac下最好的terminal是iTerm2;我用的编辑器是Emacs,但Terminal下的Emacs不能正常工作,比如M+/是我设置的hippie-expand,我不能用Alt/Command + /按出来,一定要用Esc+/ 。
被困扰了好久之后,我终于下定决心彻底解决这个问题。
NOTE:Alt/Command 指的是一个按键,在windows键盘上是Alt,Mac键盘上叫做Command,上面有一个四瓣的小花(Apple Clove)

首先要弄清楚流程:
1. 我按的键能不能传入iTerm2?
2. iTerm2如何把我的击键传到远处的Linux Terminal?
3. 远端的Terminal里的Emacs能不能正确解析击键?

1. 我按的键能不能传入iTerm2?

在Mac系统,一些组合键还真不一定能传到iTerm2,举个例子:Alt/Command + / ,这个是iTerm2里Find Cursor的Shortcuts,就是我一按这个组合键,就执行Find Cursor的功能,iTerm里的shell是收不到我的按键的。
解决方法:详细见这个邮件列表 http://groups.google.com/group/iterm2-discuss/browse_thread/thread/e960f5098ff3c4a0
就是增加一个系统级别的设置,把Find Cursor的组合键Overwrite掉。

顺便说,我顺便发现一个工具ShiftIt,就是用组合键安排窗口,比如:把窗口最大化,放在左边1/2,右边1/2…… 非常顺手。

2. iTerm2如何把我的击键传到远处的Linux Terminal?

下面是假设我按下键了,iTerm2会把我的击键传到Linux Terminal上。注意这个过程并不简单,因为我的按键会被remap,也会被改动。
举例来说,如果我按下Alt/Command,如果有remap(比如在iTerm2里设置了,或者用Double Command等设置了Remap),实际打出的可能是Option(就是Windows键盘上的Win键)。
还有一种可能是我的击键是Alt/Command,但Linux Terminal不认识Alt/Command,只有强制iTerm2把Alt/Command输出成+Esc 才成。

简单来说,在iTerm2 针对每个Session的设定里,在设定keys时,选择Preset xterm;然后把左右Option Key都选成+Esc。
另外在Linux Terminal中.inputrc文件中加入:
set input-meta on
set output-meta on
set convert-meta off

更多资料,参见在iTerm2里设置Emacs 和 paredit以及 iTerm2官方讲Keybinding的wiki

其中官方wiki指出了一个技巧,Ctrl+V,然后击键,可以看出到底快捷键具体是什么,比如Ctrl+v,然后按Esc,就会出现:”^[“, 说明Esc对应 ^[

3. 远端的Terminal里的bash/Emacs能不能正确解析击键?

Bash 常用的一个功能是backward-kill-word,就是说用快捷键向前删除单词,一般可以用Ctrl+W,还有一种常用的快捷键是Alt+Backspace。比如在iTerm2里可以Remap Alt+Backspace,但是怎么才能输入Alt+Backspace呢?直接输入时,Backspace会删除上一个字符,这时候通过查ASCII表,可以看到Hex 0x17对应backspace,那么我在iTerm2里设置0x17就可以了。

现在在Terminal 方式的Emacs里面(emacs -nw方式),应该可以用Option来代替Meta键,比如Meta+/可以用Option+/来输入。但如果我还是习惯用Alt/Command+/怎么办?
为了不在Emacs里设置,可以在iTerm2中设置 Alt/Command + / 为发送Escaped sequenced: ^[ /

假设我们按了快捷键,只有要Emacs事先知道快捷键对应什么功能才行。(例如可以用Ctrl+h k来看我们输入的快捷键对应的功能)。

经过以上三步,现在如果我需要在Emacs里输入Alt/Command + /, 可以按Esc+/ , Alt/Command + /, 或Option + / .
当然好处不止如此,比如在Emacs里各个窗口移动,可以很方便的用Shift+ArrowKey; 在一个文档快速移动,可以用Ctrl+ArrowKey。当然最大的好处是可以用Option作为Meta,以后按键就方便多了。

2016-12-09补充
如果在GNU screen里用Emacs,需要在.screenrc里加入这两行:
term xterm
c1 off

这是为了确保GNU screen不会改变键盘上输入的Escape sequence。
换句话说,可以保证“Shift+向右的箭头”可以从键盘送到Emacs程序。

使用Varnish绕过学校防火墙

Use varnish to bypass school proxy (rewrite URL to bypass port blocking).

学校的防火墙规则很严格,除了80,443等常用端口外,不允许特殊端口的通信(就连git使用的9418端口也被block过)。
可以我的网站2812端口有monit服务,我常常想从学校的电脑访问 ,看看自己网站的是不是工作正常。为了解决这个问题,我发现可以用Varnish的rewrite 功能。

原理上讲,Varnish收到一个URL request,会调用vcl_recv函数 (可能是callback机制),然后根据header中的URL来分析如何具体处理,比如可以去掉header,对mobile的browser agent用mobile版的web server,还可以用不同的backend服务器,这个就是用这个功能。

先把相应的配置放上来:
default.vcl中先添加一个后台服务器:

backend monit {
.host = "localhost";
.port = "2812";
}

在sub vcl_recv函数中增加对/monit请求的重写(rewrite),就是说每次访问xxx.com/monit自动翻译成xxx.com/, 然后用backend monit(就是上面的localhost:2812服务器)来服务:


if (req.url ~ "^/monit"){
set req.url = regsub(req.url, "^/monit", "/");
set req.url = regsub(req.url, "^//", "/");
set req.backend = monit;
}

通过上面的设置,就可以在学校里,用80端口来访问服务器端2812端口的内容了。
注意,默认monit会使用这样的链接: xxx.com/nginx
这种情况下,varnish不会用backend monit来服务,我们需要手动访问:xxx.com/monit/nginx
现在还没有想到如何解决这种不方便。

后话1:

Varnish是一个非常强大的proxy,用它内置的VCL语言,可以很灵活、高效(Varnish内部把VCL编译成C语言)处理各种类型的HTTP request。比如round-robin式的负载均衡。最常用的两个函数是vcl_recv (表示varnish接收到browser的请求) 和vcl_fetch(表示varnish已经从后台服务器取得数据)。更多的用法可以见:

后话2:

Varnish不会像Apache/Nginx把log写到磁盘。如需要检查log,可以用Varnish自带的varnishlog。
比如下面的:

   12 SessionOpen  c 76.235.186.40 34862 :80
   12 ReqStart     c 76.235.186.40 34862 911966818
   12 RxRequest    c GET
   12 RxURL        c /monit
   12 RxProtocol   c HTTP/1.1
   12 RxHeader     c Host: zhanxw.com
   12 RxHeader     c User-Agent: Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:8.0) Gecko/20100101 Firefox/8.0
   12 RxHeader     c Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
   12 RxHeader     c Accept-Language: en-us,en;q=0.5
   12 RxHeader     c Accept-Encoding: gzip, deflate
   12 RxHeader     c Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
   12 RxHeader     c Connection: keep-alive
   12 RxHeader     c Cookie: __utma=134065221.936534807.1323323714.1323329816.1323533189.3; __utmz=134065221.1323323714.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=134065221
   12 RxHeader     c Authorization: Basic YWRtaW46eGlhb3dlaXhpYW95aQ==
   12 RxHeader     c Cache-Control: max-age=0
   12 VCL_call     c recv
   12 VCL_return   c pass
   12 VCL_call     c hash
   12 VCL_return   c hash
   12 VCL_call     c pass
   12 VCL_return   c pass
   14 BackendOpen  b monit 127.0.0.1 37258 127.0.0.1 2812
   12 Backend      c 14 monit monit
   14 TxRequest    b GET
   14 TxURL        b 
   14 TxProtocol   b HTTP/1.1
   14 TxHeader     b Host: zhanxw.com
   14 TxHeader     b User-Agent: Mozilla/5.0 (Ubuntu; X11; Linux x86_64; rv:8.0) Gecko/20100101 Firefox/8.0
   14 TxHeader     b Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
   14 TxHeader     b Accept-Language: en-us,en;q=0.5
   14 TxHeader     b Accept-Encoding: gzip, deflate
   14 TxHeader     b Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
   14 TxHeader     b Cookie: __utma=134065221.936534807.1323323714.1323329816.1323533189.3; __utmz=134065221.1323323714.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=134065221
   14 TxHeader     b Authorization: Basic YWRtaW46eGlhb3dlaXhpYW95aQ==
   14 TxHeader     b X-Forwarded-For: 76.235.186.40
   14 TxHeader     b X-Varnish: 911966818
   14 RxProtocol   b HTTP/1.0
   14 RxStatus     b 400
   14 RxResponse   b Bad Request
   14 RxHeader     b Date: Sat, 10 Dec 2011 17:58:50 GMT
   14 RxHeader     b Server: monit 5.2.1
   14 RxHeader     b Content-Type: text/html
   14 RxHeader     b Connection: close
   12 TTL          c 911966818 RFC 120 1323539930 0 0 0 0
   12 VCL_call     c fetch
   12 VCL_return   c pass
   12 ObjProtocol  c HTTP/1.1
   12 ObjStatus    c 400
   12 ObjResponse  c Bad Request
   12 ObjHeader    c Date: Sat, 10 Dec 2011 17:58:50 GMT
   12 ObjHeader    c Server: monit 5.2.1
   12 ObjHeader    c Content-Type: text/html
   14 Length       b 201
   14 BackendClose b monit
   12 VCL_call     c deliver
   12 VCL_return   c deliver
   12 TxProtocol   c HTTP/1.1
   12 TxStatus     c 400
   12 TxResponse   c Bad Request
   12 TxHeader     c Server: monit 5.2.1
   12 TxHeader     c Content-Type: text/html
   12 TxHeader     c Content-Length: 201
   12 TxHeader     c Date: Sat, 10 Dec 2011 17:58:50 GMT
   12 TxHeader     c X-Varnish: 911966818
   12 TxHeader     c Age: 0
   12 TxHeader     c Via: 1.1 varnish
   12 TxHeader     c Connection: keep-alive
   12 Length       c 201
   12 ReqEnd       c 911966818 1323539930.287971973 1323539930.288527966 0.000089884 0.000468969 0.000087023
   12 Debug        c "herding"

其中最重要的是第3列: b 表示 “backend”,就是varnish和backend端的通信; c 表示 “client”,就是varnish和client端(www browser)之间的通信。

第2列中, VCL_call 表示varnish内部哪个函数被调用,VCL_return则是调用结果是什么。比如:VCL_call retch ,表示VCL配置文件中vcl_fetch函数被调用; VCL_return pass,表示return pass,同样也是VCL配置文件中的语句。

使用Intel Compiler Suite和Intel MKL编译64位R

Compiling 64bit R using Intel Compiler (icc/ifort) and Intel Math Kernel Library (MKL).
通过Intel的编译器和Intel MKL,我们得到运行速度最快的R系统(比上一篇介绍的 R+GotoBlas 还快一点点)。

下载,安装Intel Parallel Studio,这个包括Intel C compiler (icc), C++ Compiler (icpc), Fortran compiler(ifort):
http://software.intel.com/en-us/articles/intel-parallel-studio-xe/

下载,安装Intel Math Kernel Library
http://software.intel.com/en-us/articles/intel-mkl/
Intel的这两个软件对于非商业用途是免费的。

然后需要下载R的源代码:
http://cran.cnr.berkeley.edu/

解压缩R之后,在其目录下建立bash文件来指定编译的方式(R本身是使用静态链接还是动态链接库?安装路径?)。
具体方式可以在这个脚本的末尾部分找到,大家可以自己按需要修改。
注:在我的比较下,使用动态链接的BLAS库与静态链接库相比不会损失速度;使用动态链接库的优点是可以方便的换用不同BLAS库。

source /home/zhanxw/intel/composer_xe_2011_sp1.6.233/bin/iccvars.sh intel64                                                                                   
source /home/zhanxw/intel/composer_xe_2011_sp1.6.233/bin/ifortvars.sh intel64
source /home/zhanxw/intel/composer_xe_2011_sp1.6.233/mkl/bin/mklvars.sh intel64

export CC=icc
export CFLAGS="-O3 -wd188 -mieee-fp"
export F77=ifort
export FFLAGS="-O3 -mieee-fp"
export CXX=icpc
export CXXFLAGS="-O3"
export FC=ifort
export FCFLAGS="-O3 -mieee-fp"
export ICC_LIBS=/home/zhanxw/intel/composer_xe_2011_sp1.6.233/compiler/lib/intel64
export IFC_LIBS=/home/zhanxw/intel/composer_xe_2011_sp1.6.233/compiler/lib/intel64
export SHLIB_CXXLD=icpc
export SHLIB_CXXLDFLAGS=-shared

MKL_LIB_PATH=/home/zhanxw/intel/composer_xe_2011_sp1.6.233/mkl/lib/intel64
export LD_LIBRARY_PATH=$MKL_LIB_PATH

OMP_NUM_THREADS=8

export LDFLAGS="-L${MKL_LIB_PATH},-Bdirect,--hash-style=both,-Wl,-O1 -L$ICC_LIBS -L$IFC_LIBS -L/usr/local/lib"

export SHLIB_LDFLAGS="-lpthread"
export MAIN_LDFLAGS="-lpthread"

MKL="-L${MKL_LIB_PATH} -lmkl_blas95 -lmkl_lapack95  -Wl,--start-group -lmkl_intel -lmkl_intel_thread -lmkl_core -Wl,--end-group -openmp -lpthread"

OMP_NUM_THREADS=8

MKL="-L${MKL_LIB_PATH} -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread"
#static linked library of R                                                                                                                                   
#./configure --with-blas="$MKL"  --with-lapack="$MKL" --prefix=/net/dumbo/home/zhanxw/software/Rmkl                                                           

# dynamic linked library of: R and BLAS                                                                                                                       
#./configure --enable-R-shlib --enable-BLAS-shlib --with-blas="$MKL"  --with-lapack="$MKL" --prefix=/net/dumbo/home/zhanxw/software/Rmkl                      

#dynamic linked library of: BLAS                                                                                                                              
./configure --enable-BLAS-shlib --with-blas="$MKL"  --with-lapack="$MKL" --prefix=/net/dumbo/home/zhanxw/software/Rmkl

之后用make; make install即可。
使用同样的R-benchmark脚本,结果如下:
Intel Compiler (ICC+Ifort) and Intel MKL

   R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.719666666666667 
2400x2400 normal distributed random matrix ^1000____ (sec):  0.394333333333333 
Sorting of 7,000,000 random values__________________ (sec):  0.861 
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  0.709 
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  0.448 
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  0.611437229773395 

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.907666666666668 
Eigenvalues of a 640x640 random matrix______________ (sec):  0.613000000000001 
Determinant of a 2500x2500 random matrix____________ (sec):  0.493333333333333 
Cholesky decomposition of a 3000x3000 matrix________ (sec):  0.334333333333332 
Inverse of a 1600x1600 random matrix________________ (sec):  0.611666666666667 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.569777440099831 

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  0.82 
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.535999999999999 
Grand common divisors of 400,000 pairs (recursion)__ (sec):  2.64933333333334 
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.683666666666667 
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  0.828000000000003 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.774276714018349 


Total time for all 15 tests_________________________ (sec):  11.609 
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  0.646126830621363 
                      --- End of test ---

Intel Compiler(ICC+Ifort) + GotoBlas2(Compiled by ICC/Ifort)

   R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.715333333333333
2400x2400 normal distributed random matrix ^1000____ (sec):  0.41
Sorting of 7,000,000 random values__________________ (sec):  0.862666666666666
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  0.829333333333333
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  0.554666666666667
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  0.690382674196494

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.922333333333332
Eigenvalues of a 640x640 random matrix______________ (sec):  0.681333333333333
Determinant of a 2500x2500 random matrix____________ (sec):  0.511666666666667
Cholesky decomposition of a 3000x3000 matrix________ (sec):  0.433333333333332
Inverse of a 1600x1600 random matrix________________ (sec):  0.594333333333331
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.591732764155743

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  0.835999999999999
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.545000000000002
Grand common divisors of 400,000 pairs (recursion)__ (sec):  2.66133333333333
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.695666666666665
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  0.585000000000001
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.698105585240407


Total time for all 15 tests_________________________ (sec):  11.838
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  0.658231817116501
                      --- End of test ---

常见的错误:
在编译R的时候,我们用–with-blas=”$MKL”来制定Intel MKL的位置 (网上其他文章的做法),但如果$MKL的值不正确,R无法正常链接MKL。我们需要检查configure的输出或者文件config.log,要确保这两项的检查都是yes:
checking for dgemm_ in -L/home/zhanxw/intel/composer_xe_2011_sp1.6.233/mkl/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread… yes
checking whether double complex BLAS can be used… yes
checking whether the BLAS is complete… yes

值得指出的是在链接Intel库时,LP64 和 ILP64是不同的。在我的机器上,错误的制定ILP64,例如-lmkl_intel_ilp64,会导致R无法使用MKL,因为使用ILP64编译的程序会crash(在configure脚本里,这个文件是conftest)

config.log是非常有用的文件,它包括的configure检查系统环境时相关信息,通过这个文件并结合configure(本质是一个shell script),可以帮助我们确定R是否可以,或者为什么不可以链接MKL库。

另外,使用shared BLAS库的时候R会检查zgeev_,并检查不到MKL,这个R“有意”的结果。因为动态的MKL库会包含LAPACK的信息。如果介意这方面的速度损失,可以使用静态链接的方式。

Updated (2011-10-05):

Similar idea in the PPT format:

R_BLAS-Sachdeva

加速R的矩阵运算(Speed up R matrix computation)

Speed up R matrix computation with smallest effort.

给R提速有两个方法:
1. 使用Intel compiler
2. 使用更快的矩阵运算库

其中我使用第一个方法并没有看到显著的速度提升,所以这里介绍第2种方法,保证矩阵运算至少提速2倍。
我使用的是R-2.13.1版本,矩阵库使用GotoBLAS。
根据下面这个链接,
http://r.789695.n4.nabble.com/configure-can-t-find-dgemm-in-MKL10-td920212.html
GotoBLAS比Intel MKL快。据说,GotoBLAS比ATLAS也要快。

具体步骤如下:
(1)建立一个shell 源文件:

export FFLAGS="-march=native -O3"
export CFLAGS="-march=native -O3 -DMKL_ILP64"
export CXXFLAGS="-march=native -O3 -DMKL_ILP64"
export FCFLAGS="-march=native -O3"

./configure --enable-R-shlib --enable-BLAS-shlib --with-blas --with-lapack --prefix=/net/dumbo/home/zhanxw/software/Rmkl                  

之后用make, make install安装。
(2)下载GotoBLAS,在源目录’make’即可,得到的BLAS库文件名是’libgoto2.so’
(3)建立符号链接。在R安装目录下e.g. /lib64/R/lib,已经有一个R默认的BLAS动态连接库libRblas.so,把这个改成链接到libgoto2.so的符号链接。

这3步之后,R就会使用GotoBLAS作为矩阵运算库。在我们的服务器上,benchmark结果如下:
# GCC + default BLAS

   R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.764666666666666
2400x2400 normal distributed random matrix ^1000____ (sec):  0.596666666666666
Sorting of 7,000,000 random values__________________ (sec):  0.833333333333333
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  4.425
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  2.30366666666667
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  1.13650194597564

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.778666666666666
Eigenvalues of a 640x640 random matrix______________ (sec):  1.406
Determinant of a 2500x2500 random matrix____________ (sec):  2.28733333333334
Cholesky decomposition of a 3000x3000 matrix________ (sec):  2.02366666666667
Inverse of a 1600x1600 random matrix________________ (sec):  1.933
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  1.76516531172197

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  1.06166666666667
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.601666666666669
Grand common divisors of 400,000 pairs (recursion)__ (sec):  2.56866666666667
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.757666666666661
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  0.595000000000013
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.785128552514896


Total time for all 15 tests_________________________ (sec):  22.9366666666667
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  1.16349747864837
                      --- End of test ---

# GCC + GotoBLAS(GCC)

  R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.776333333333333
2400x2400 normal distributed random matrix ^1000____ (sec):  0.597
Sorting of 7,000,000 random values__________________ (sec):  0.838
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  0.376333333333333
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  0.293
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  0.558725402933605

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.785666666666668
Eigenvalues of a 640x640 random matrix______________ (sec):  2.092
Determinant of a 2500x2500 random matrix____________ (sec):  0.303666666666667
Cholesky decomposition of a 3000x3000 matrix________ (sec):  0.292999999999999
Inverse of a 1600x1600 random matrix________________ (sec):  0.396333333333331
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.455580734019386

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  1.07166666666667
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.608999999999999
Grand common divisors of 400,000 pairs (recursion)__ (sec):  2.848
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.675666666666665
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  0.591000000000001
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.761149272082565


Total time for all 15 tests_________________________ (sec):  12.5466666666667
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  0.578643662905733
                      --- End of test ---


# ICC + build-in BLAS

   R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.722333333333333
2400x2400 normal distributed random matrix ^1000____ (sec):  0.398
Sorting of 7,000,000 random values__________________ (sec):  0.853333333333333
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  23.2723333333333 
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  9.48066666666666 
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  1.80121303632586 

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.919666666666667 
Eigenvalues of a 640x640 random matrix______________ (sec):  1.01100000000001 
Determinant of a 2500x2500 random matrix____________ (sec):  4.84600000000001 
Cholesky decomposition of a 3000x3000 matrix________ (sec):  3.71033333333332 
Inverse of a 1600x1600 random matrix________________ (sec):  6.53100000000001 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  2.62935462784594 

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  0.825333333333333 
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.588666666666654 
Grand common divisors of 400,000 pairs (recursion)__ (sec):  2.65866666666667 
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.665000000000001 
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  0.55400000000003 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  0.686183322572556 


Total time for all 15 tests_________________________ (sec):  57.0363333333334 
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  1.4812151139281 
                      --- End of test ---

# ICC + GotoBLAS(ICC)

   R Benchmark 2.5
   ===============
Number of times each test is run__________________________:  3

   I. Matrix calculation
   ---------------------
Creation, transp., deformation of a 2500x2500 matrix (sec):  0.738666666666667
2400x2400 normal distributed random matrix ^1000____ (sec):  0.388000000000001
Sorting of 7,000,000 random values__________________ (sec):  0.857333333333333 
2800x2800 cross-product matrix (b = a' * a)_________ (sec):  0.633333333333333 
Linear regr. over a 3000x3000 matrix (c = a \ b')___ (sec):  0.537666666666667 
                      --------------------------------------------
                 Trimmed geom. mean (2 extremes eliminated):  0.631245051729315 

   II. Matrix functions
   --------------------
FFT over 2,400,000 random values____________________ (sec):  0.938333333333333 
Eigenvalues of a 640x640 random matrix______________ (sec):  5.53166666666667 
Determinant of a 2500x2500 random matrix____________ (sec):  0.957666666666666 
Cholesky decomposition of a 3000x3000 matrix________ (sec):  0.601000000000001 
Inverse of a 1600x1600 random matrix________________ (sec):  1.741 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  1.16088739499808 

   III. Programmation
   ------------------
3,500,000 Fibonacci numbers calculation (vector calc)(sec):  0.813 
Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec):  0.591333333333334 
Grand common divisors of 400,000 pairs (recursion)__ (sec):  2.663 
Creation of a 500x500 Toeplitz matrix (loops)_______ (sec):  0.669333333333332 
Escoufier's method on a 45x45 matrix (mixed)________ (sec):  4.883 
                      --------------------------------------------
                Trimmed geom. mean (2 extremes eliminated):  1.13162201708511 


Total time for all 15 tests_________________________ (sec):  22.5443333333333 
Overall mean (sum of I, II and III trimmed means/3)_ (sec):  0.939499363744844 
                      --- End of test ---

通过比较GCC/ICC 与 R自带的BLAS/GotoBLAS的4种组合,在我们的服务器系统下GCC+GotoBLAS最快。

注:
LAPACK是对BLAS的再次封装,因此我们不需要改变libRlapack.so。这一点可以通过’nm -g libRlapack.so’,查看dgemm_的定义为‘U’(说明这个函数没有在该文件中实现),而通过’ldd libRlapack.so’可以发现它会调用libRblas.so

其他资源: