J

MacのRの行列演算を高速化

1. 背景

Mac限定の方法だが、Appleは各デバイスごとに数値計算アルゴリズムを最適化しており、accelerate.framework(vecLib)といった名前で標準装備されている。

BLASLAPACKなどが実装されている。

Rへの適用方法は、BLASシンボリックリンクを変更するだけだ。

2. 方法

ターミナル上で

cd /Library/Frameworks/R.framework/Resources/lib
ln -sf /System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Versions/Current/libBLAS.dylib libRblas.dylib

とすることで適用される。 Rstudioでも適用される。

3. テスト

これを用いて、行列演算テストを行う。 以下、結果を記載する。

################################################
### MacBook Pro (Retina, 15-inch, Late 2013) ###
################################################
system.time(solve(matrix(runif(3000*3000),3000,3000)))['elapsed']
#       elapsed 
# 設定前  48.756 
# 設定後    1.25 

set.seed(0)
T <- 5
N <- 2000
A <- matrix(rnorm(N * N), N, N)

## Matrix multiplication
t1 <- sapply(1 : T, function(t) system.time(A %*% A)['elapsed'])
 
## Matrix inversion
t2 <- sapply(1 : T, function(t) system.time(solve(A))['elapsed'])
 
## Eigenvalues/vectors
t3 <- sapply(1 : T, function(t) system.time(eigen(A))['elapsed'])

## Linear regression
D <- as.data.frame(A)
t4 <- sapply(1 : T, function(t) system.time(lm(V1 ~ ., data=D))['elapsed'])

t1
#       elapsed elapsed elapsed elapsed elapsed 
# 設定前   4.822   4.801   4.929   4.821   4.921 
# 設定後   0.121   0.137   0.130   0.131   0.125 

t2
#       elapsed elapsed elapsed elapsed elapsed 
# 設定前  14.338  14.312  14.399  14.665  14.289 
# 設定後   0.311   0.280   0.279   0.284   0.297 
t3
#       elapsed elapsed elapsed elapsed elapsed 
# 設定前  38.313  37.788  37.910  37.739  38.073
# 設定後   6.427   6.360   6.359   6.426   6.595 
t4
#       elapsed elapsed elapsed elapsed elapsed 
# 設定前   4.378   4.256   4.218   4.189   4.220 
# 設定後   2.490   2.410   2.380   2.419   2.384 

かなり高速化されていることが分かる。

参考

Accelerate(7) Mac OS X Manual Page https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man7/Accelerate.7.html

sshのプロキシ環境を自動切り替え

1. 目的

自宅と職場(あるいは学校など)でノートPCを持ち歩いていると、職場のプロキシ環境に設定したりする。 たとえば、プログラム言語Rはプロキシの設定を書いておかないと、install.packages()を使えなかったりする。 sshも例外ではない。プロキシ環境では、それに合わせて~/.ssh/configなどに設定をしておかなければならない。

しかし、いちいちネットワーク環境が変わるたびに設定ファイルを書き換えていては面倒である。ネットワーク環境に合わせて自動で切り替えてくれると便利だ。

特に、以前紹介した、homebrew-fileを利用する場合、この設定は有効である。

2. 方法

以前の記事

Mac のターミナルで、プロキシ設定を環境に合わせて自動切替 - joker8phoenix's diary

を拡張する。

ここでは、ターミナルを起動するたびに読み込まれる~/.bashrcを利用する。

2.1. 準備

ここでは、例として、github.comssh接続する場合を考える。 例として、

  • プロキシ環境を設定したネットワーク接続名: proxy
  • プロキシのアドレス: proxy.example.com
  • プロキシのポート: 8080

とする。

2.1.1. ~/.ssh/configファイルの準備

まず、sshconfigファイルに対して、プロキシ環境でない場合とプロキシ環境の場合の2つを準備する。

ターミナルにて

vi ~/.ssh/config_no_proxy

とし、config_no_proxyの内容を

Host github.com
   User git
   Port 22
   Hostname github.com
   IdentityFile ~/.ssh/id_rsa

とする。

sshの鍵をid_rsaとしている。自身の鍵に合わせて、適宜書き換えていただきたい。

さらに、続けてターミナルにて

vi ~/.ssh/config_proxy

とし、config_proxyの内容を

Host github.com
  User git
  Port 443
  Hostname ssh.github.com
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand corkscrew proxy.example.com 8080 %h %p

とする。

もしcorkscrewをインストールしていない場合は、ターミナルにて

brew install corkscrew

として、インストールしておこう。

なお、プロキシのアドレスとポートは環境に合わせて適宜書き換えていただきたい。

さらに、ターミナルにて

cp ~/.ssh/config_no_proxy ~/.ssh/config
ln -fs ~/.ssh/config_no_proxy ~/.ssh/config

としておく。こうすることで、sshconfigを経由してconfig_no_proxyを読み込むようになる。

2.1.2. ~/.bashrcに記述

ターミナルにて

vi ~/.bashrc

として、その内容に以下を記述する。

#############################
### proxy trigger setting ###
#############################

# 例として、
# システムのネットワーク接続環境の名前が、proxy
# プロキシのアドレス: proxy.example.com
# プロキシのポート: 8080
# の場合
proxy=http://proxy.example.com:8080
switch_trigger=proxy # ネットワーク接続の名前

# プロキシ環境ではない場合の設定ファイルにリンクを貼る
ln -fs ~/.ssh/config_no_proxy ~/.ssh/config

if [ "`networksetup -getcurrentlocation`" = "$switch_trigger" ]; then
   export HTTP_PROXY=$proxy
   export HTTPS_PROXY=$proxy
   export ALL_PROXY=$proxy
   
   # プロキシ環境の設定ファイルにリンクを貼る
   ln -fs ~/.ssh/config_proxy ~/.ssh/config
fi

ターミナルを起動するたびに、.bashrcが読み込まれて、そのときのネットワーク環境を取得し、もしもプロキシ環境であればifからfiまでに記述した内容が実行される。

これにより、~/.ssh/configシンボリックリンクは、ネットワーク環境に合わせて、適切な設定ファイルへとリンク付けされる。

以後、sshを利用するときにネットワーク環境を意識する必要はない。とても便利。

なお、Rでプロキシ環境に合わせる場合は、~/.Renviron

http_proxy=http://proxy.example.com:8080/

を記述すると良い。これも、プロキシ用とそうでないものを2つ用意して、同じ方法で利用できる(と思われるが、試していない)。

以上。

参考文献

Mac のターミナルで、プロキシ設定を環境に合わせて自動切替 - joker8phoenix's diary