上図のように英字入力を入力ソースとして加える。
するとことえりを削除するための-ボタンが有効になるので、押す。
消える。
SOFTWARE=$HOME/.software tar xvf ghc-6.8.3-x86_64-unknown-linux.tar.bz2 cd ghc-6.8.3 CC=gcc44 ./configure --prefix=$SOFTWARE/ghc-6.8.3 make install特に問題なくインストールできた。
export PATH=$SOFTWARE/ghc-6.8.3/bin:$PATH cd ../ tar xvf ghc-6.10.4-src.tar.bz2 cd ghc-6.10.4 ./configure --prefix=$SOFTWARE/ghc-6.10.4 --with-gcc=gcc44 make && make installmakeに失敗。bfd.hのところで、#error config.h must be included before this header みたいなエラーがでた。Stackoverflowの投稿によると、autotools?を使っていないためPACKAGEとPACKAGE_NAMEがdefineされておらず怒られているっぽい。とりあえずの解決策として、怒られていたrts/Printer.cの先頭部分に
#define PACKAGE 1 #define PACKAGE_NAME 1を入れて再度makeしたらコンパイルが通った。
export PATH=$SOFTWARE/ghc-6.10.4/bin:$PATH cd ../ tar xvf ghc-7.0.3-src.tar.bz2 cd ghc-7.0.3 ./configure --with-gcc=gcc44 make && make install先ほどと同じbfd.hでこけるので同じ対応をしてビルド成功。
export PATH=$SOFTWARE/ghc-7.0.3/bin:$PATH cd ../ tar xvf haskell-platform-2011.2.0.1.tar.gz cd haskell-platform-2011.2.0.1 ./configure --prefix=$SOFTWARE/haskell-platform --with-gcc=gcc44 make make install問題なく成功。あとは.bashrcなどに以下のようなものを追加すれば良い。インストールの時に使ったファイルや古いGHCは消しても良い(と思う)。
SOFTWARE=$HOME/.software export PATH=$SOFTWARE/haskell-platform/bin:$SOFTWARE/ghc-7.0.3/bin:$PATH
couldn't read caba file xxxx.cabal的なことを言われる。stackoverflowのRichard曰く、cabalファイルのフォーマットが変わってしまい、古いcabalで読めないとのこと。新しいCabalをhttp://hackage.haskell.org/packages/archive/cabal-install/1.16.0.2/cabal-install-1.16.0.2.tar.gzからダウンロードしてREADMEの指示に従いインストールすることで解決ができるとのこと。
wget http://hackage.haskell.org/packages/archive/cabal-install/1.16.0.2/cabal-install-1.16.0.2.tar.gz tar xvf cabal-install-1.16.0.2.tar.gz cd cabal-install-1.16.0.2 chmod +x bootstrap.sh ./bootstrap.sh$HOME/.cabal/binにバイナリができるので、忘れずにパスを通す設定をする。
/home/git/gitlab-shell/bin/gitlab-shell:8: undefined method `require_relative' for main:Object (NoMethodError)どうやらrvmで設定したruby1.9.3が呼ばれていない模様。ユーザーgit向けにrvmはインストール済みでログインするとちゃんと
which ruby /home/git/.rvm/rubies/ruby-1.9.3-p392/bin/rubyとでる。 実はgit cloneは内部的にはSSHでgitユーザーでgitサーバーに接続して、サーバー側の~git/.ssh/authorized_keysに書かれたコマンドを実行するようになっている。そのコマンドは~git/gitlab-shell/bin/gitlab-shellを呼び出す。それがruby >1.9.2以上であることを想定して書かれている。
#! /bin/bash # RVM installed with single-user mode PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session as a function # RVM installed with multi-user mode #RVMSH_PATH="/etc/profile.d/rvm.sh" #[[ -s $RVMSH_PATH ]] && source $RVMSH_PATH # Load RVM into a shell session as a function exec /home/git/gitlab-shell/bin/gitlab-shell.real $@
taro$ \curl -L https://get.rvm.io | sudo bash -s stableもしプロキシを使っていてうまく行かなかった場合は、環境変数HTTPS_PROXYをtaroで設定していたら、sudoに環境変数を渡すために-Eオプションをつけます。この後も、ネットワーク問題でハマったら、sudo -Eとしてください。
taro$ \curl -L https://get.rvm.io | sudo -E bash -s stable
taro$ sudo usermod -aG rvm taro
source /etc/profile.d/rvm.sh
taro$ id
taro$ rvm install 1.9.3 taro$ rvm use --default 1.9.3この時点ではbundlerはインストールしない。あとで、ユーザーgitlab(3. System Usersで追加される)だけにインストールする。
taro$ sudo su - gitlab~/.bashrcなどに"source /etc/profile.d/rvm.sh"を追加して再読み込み。
gitlab$ source .bashrcgitlabユーザー固有のgemsetを作る。
gitlab$ rvm user gemsets gitlab$ rvm istall 1.9.3 gitlab$ rvm use --default 1.9.3 gitlab$ rvm gemset create gitlab$ rvm gemset use default gitlab$ rvm gemset install bundler gitlab$ rvm gemset install charlock_holmes --version '0.6.9'DBにはMySQLを使ったので、without postgresでインストール。
gitlab$ cd /home/gitlab/gitlab gitlab$ bundle install --deployment --without development test postgres
taro$ sudo su - gitlab gitlab$ cd gitlab gitlab$ bundle exec rake gitlab:setup RAILS_ENV=productionここでしくじる。execコマンドがないと怒られる。調べると、issueが投稿されてた。Squeeze-backportsリポジトリからredis-serverを入れなおせとのこと。多分RedisServerが古かったのかと思われる。Ubuntu10.04。リポジトリを追加するために、/etc/apt/sources.list.d/squeeze-backports.listというファイルに
deb http://backports.debian.org/debian-backports squeeze-backports main
taro$ sudo apt-get update
taro$ sudo -E apt-key adv --keyserver keyserver.ubuntu.com --recv-keys AED4B06F473041FA taro$ sudo apt-get update taro$ sudo apt-get remove redis-server taro$ sudo apt-get -t squeeze-backports install redis-server
gitlab$ bundle exec rake gitlab:setup RAILS_ENV=production
taro$ sudo su - gitlab gitlab$ cd gitlab gitlab$ bundle exec rake gitlab:env:info RAILS_ENV=production gitlab$ bundle exec rake gitlab:check RAILS_ENV=productionこれで動きました。ローカルではない場合もservernameなどちゃんと設定すれば動きます。 参考: http://d.hatena.ne.jp/hiro_nemu/20120811/1344656084
def numpy_mult3_0_pure(npArr):
for r in xrange(npArr.shape[0]):
for c in xrange(npArr.shape[1]):
if (r + c) % 3 == 0:
npArr[r, c] = 0
これを次のように呼び出す。
>>> side = 1000 >>> npArr = np.ones((side, side)) >>> numpy_mult3_0_pure(npArr) >>> print npArr結果は、以下。
[[ 0. 1. 1. ..., 1. 1. 0.] [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] ..., [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] [ 0. 1. 1. ..., 1. 1. 0.]]まったく前回のコピペです。
def numpy_mult3_0_weave(npArr):
code = """
for(int r = 0; r < NnpArr[0]; r++) {
for(int c = 0; c < NnpArr[1]; c++) {
if((r + c) % 3 == 0) {
NPARR2(r, c) = 0;
}
}
}
"""
weave.inline(code, ['npArr'])
前回やった、N+(変数名), (変数名大文字)+(次元数)のアクセス用マクロ関数を使えば、上のように書けるのです。どのくらい早くなるのか時間を計測してみます。
side = 1000
npArr = np.ones((side, side))
from context_timer import Timer
with Timer("Pure"):
numpy_mult3_0_pure(npArr)
with Timer("Weave"):
numpy_mult3_0_weave(npArr)
このTimerについてはこちらの記事をご覧ください。出力は以下です。[Pure] Elapsed: 0.272620201111 [Weave] Elapsed: 0.00578308105469Weaveの方が50倍近く早くなっていることがわかります。こんな感じにPythonコードにC++のコードを書くことで高速化することができます。
import numpy as np # numpyのインポート # 乱数配列の生成 2行3列 a = np.random.rand(2,3) b = np.random.rand(2,3) # 各要素ごとの掛け算 Matlabだと a .* b c = a * b # 行列としての掛け算 Matlabだと a' * b d = np.dot(a.T, b) # C = A^T * B (Cは2行2列になります) # 固有値分解 [E, V] = np.linalg.eig(d)Matlabでできることはほぼ全部できます。しかも、無料で。このページは参考になります。Numpy for Matlab Users
def numpy_mult3_0_pure(npArr):
for r in xrange(npArr.shape[0]):
for c in xrange(npArr.shape[1]):
if (r + c) % 3 == 0:
npArr[r, c] = 0
これを次のように呼び出す。
>>> side = 1000 >>> npArr = np.ones((side, side)) >>> numpy_mult3_0_pure(npArr) >>> print npArr結果は、以下。
[[ 0. 1. 1. ..., 1. 1. 0.] [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] ..., [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] [ 0. 1. 1. ..., 1. 1. 0.]]時間を計測すると、0.384463787079[秒]でした。 これをWeaveを使ってC化して高速化します。この例に移る前にNumpyをWeaveに使う場合の基本から見ていきます。 weave.inlineはPython変数を渡すと自動的にC内で適当な型に変換してくれます(converterを指定することも可能)。Numpyのndarrayを渡した場合も自動で色々と変換を施してくれます。次の例を見てみます。
def numpy_converted_vars():
npArr = np.zeros((2, 3, 4), dtype=np.uint16)
npArr[1, 1, 3] = 1
print '(py) ndim:', npArr.ndim
print '(py) shape:', npArr.shape
print '(py) strides:', npArr.strides
code = """
// Number of dimension
std::cout << "ndim: " << DnpArr << std::endl;
// Shape
std::cout << "shape:";
for (int i = 0; i < DnpArr; i++) std::cout << " " << NnpArr[i];
std::cout << std::endl;
// Strides
std::cout << "strides:";
for (int i = 0; i < DnpArr; i++) std::cout << " " << SnpArr[i];
std::cout << std::endl;
// Access to data as a three dimensional array
std::cout << "npArr[1, 1, 3]: " << NPARR3(1, 1, 3) << std::endl;
"""
weave.inline(code, [u'npArr'])
このメソッド内では、まず2×3×4の形のすべての要素が0の3次元配列を作ります。確認の為に[1,1,3]の要素だけ1を代入しておきます。
データ型がuint16=2[bytes]で、3次元、C-contiguousのメモリ上のデータ配置で、2 * 3 * 4の形なので、上の3つのprintの結果は
(py) ndim: 3 (py) shape: (2, 3, 4) (py) strides: (24, 8, 2)となります。stridesのところとかよくわからない人はこの画像を見て理解するかググってください。
PyArrayObject* npArr_array = convert_to_numpy(py_npArr,"npArr");NumpyのC APIについては各自ぐぐって欲しいのですが、PyArrayObject構造体のメンバにstridesなどがあるので、
npy_intp* NnpArr = npArr_array->dimensions; npy_intp* SnpArr = npArr_array->strides; int DnpArr = npArr_array->nd;で値を取り出してくれています。inlineコードのndim, shape, stridesの出力は次のようになり、python側での出力と一致しています。
ndim: 3 shape: 2 3 4 strides: 24 8 2肝心のnpArrという名前は以下のように配列のデータへの先頭ポインタのアドレスを取り出したものとして宣言しています。
double* npArr = (double*) npArr_array->data;一次元配列としてアクセスする場合はnpArr[0]などとアクセスすれば値を取り出せますが、この例では3次元配列なので、stridesを使って要素にアクセス必要があります。たとえばnpArr[i, j, k]にアクセスしたい場合は、以下のようにする必要があります(PyArrayObject*->dataはchar*型)。
*((double*)(npArr_array->data + (i * SnpArr[0] + j * SnpArr[1] + k * SnpArr[2])))しかし、これはめんどくさい。実はこれをやるためのマクロ関数を最高4次元配列の場合まで定義してくれています。
#define NPARR1(i) (*((double*)(npArr_array->data + (i)*SnpArr[0]))) #define NPARR2(i,j) (*((double*)(npArr_array->data + (i)*SnpArr[0] + (j)*SnpArr[1]))) #define NPARR3(i,j,k) (*((double*)(npArr_array->data + (i)*SnpArr[0] + (j)*SnpArr[1] + (k)*SnpArr[2]))) #define NPARR4(i,j,k,l) (*((double*)(npArr_array->data + (i)*SnpArr[0] + (j)*SnpArr[1] + (k)*SnpArr[2] + (l)*SnpArr[3])3次元配列の場合はnpArrの名前を大文字にして後ろに3をつけた名前が付けられていますので、上のようにpython側でnpArr[1,1,3]=1で変更した値にNPARR3(1,1,3)でアクセスできています。
npArr[1, 1, 3]: 1今回はNumpyのweave.inlineへの受け渡しの基本を紹介しました。次回に実際計算してみます。
# context_timer.py
import time
import sys
class Timer(object):
def __init__(self, name=None, out=sys.stdout):
self.name = name
self.out = out
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
if self.name:
print >> self.out, '[%s]' % self.name,
print >> self.out, 'Elapsed: %s' % (time.time() - self.tstart)
これを使って、1から1000までの整数の和を計算する時間を測る場合は次のようにwith文を使います。
from context_timer import Timer
with Timer("Sum"):
val = 0
for i in xrange(1, 1001):
val += i
print val
出力は次のようになります。
500500 [Sum] Elapsed: 0.00104784965515
>>> a= np.ones(10, dtype=np.uint8) >>> a /= 10.0 >>> print a [0 0 0 0 0 0 0 0 0 0]
def normalize(arr):
arr /= arr.sum()
というメソッドがあったとして、これに整数型を渡すと切り捨てられてしまうので、浮動少数型に限定したい。この場合、np.issubdtypeというメソッドで型が整数か浮動少数か調べます。def normalize(arr):
if np.issubdtype(arr.dtype, np.integer):
raise ValueError("arr must be float.")
arr /= arr.sum()
みたいな感じ。浮動少数か調べるにはnp.floatを使えばいいはず。def test_ret_int():
print "---- Return int ----"
code = """
return_val = 1;
"""
ret = weave.inline(code)
print "ret:", ret
Cの中でint型作成して返すサンプルです。Cのコードから値を返すときには、決してreturn文を使わないでください。weave内では、codeに書かれたコードに到達する前にreturn_valというSCXXのpy::objectが宣言されています。(生成されたcppファイルを見るとわかります。)return_valに代入された変数はweave.inlineメソッドの戻り値として受け取ることができます。APIを見るとわかりますが、py::objectのCの数値型や文字列型を代入すると、自動的にPythonのオブジェクトに変換してくれます。結果は次のようになります。---- Return int ---- ret: 1
def test_ret_tuple():
print "---- Return tuple ----"
code = """
if(scxxFlag) {
// scxx
py::tuple ret(2);
py::object tmp(1); ret.set_item(0, tmp);
tmp = 3.5; ret.set_item(1, tmp);
return_val = ret;
} else {
// Python C API is more reasnable.
return_val = Py_BuildValue("id", 1, 3.5);
}
"""
scxxFlag = 1
ret = weave.inline(code, ["scxxFlag", ])
print "ret (scxx):", ret
scxxFlag = 0
ret = weave.inline(code, ["scxxFlag", ])
print "ret (Py/C API):", ret
return_valはpy::object型なので、SCXXのpy::tuple, py::dictなどを代入することも可能ですし、Python/C APIのPyObject*を渡すこともできます。ここでは、if文のscxxFlagが1の場合はSCXXでtupleを、0の場合はPython/C APIでtupleを作成しています。(boolの受け渡しはサポートしていないっぽいので、scxxFlagをbool型にしませんでした。)
出力は以下。
---- Return tuple ---- ret (scxx): (1, 3.5) ret (Py/C API): (1, 3.5)両方とも同じ結果になっていますね。 Python/C APIの Py_BuildValue はとても便利なので使った方が良いと思います。フォーマットのiはint、dはdouble, sは文字列(char*), OはPyObject*を意味します。 listもdictも簡単に生成できるので試してみてください。
return_val = Py_BuildValue("[i,d]", 1, 3.5);// List
return_val = Py_BuildValue("{s:i,s:[d,s]}", "abc", 1, "def", 3.5, "Hoge"); // Dict
前回の例とあわせて、これで値の受け渡しができるようになりました。次回は、数値計算を利用している方向けにNumpyのArrayを利用した例を見ていきます。
def test_pass_int():
print "---- Pass int ----"
val = 1
code = """
std::cout << "val: " << val << std::endl;
"""
weave.inline(code, ['val', ], headers=['', ])
結果は次のようになります。---- Pass int ---- val: 1weave.inlineの第2引数はargs=[]のオプション引数であり、Cのコード内に渡したいPython側の変数名を文字列のリストとして渡します。すると、inlineはPython側でローカル変数またはグローバル変数で使われている変数を探します。そして、見つかった変数を適切な型に変換してCコードの中で使えるようにしてくれます。上の例ではvalはPythonのPyInt型なのでC側ではそのまま使えないはずですが、ちゃんとCのint型に変換してくれます。ここでさり気なく、C++スタイルの標準出力プリントを使いました。cout, endlを使うには<iostream>が必要なので、オプション引数headersにヘッダの文字列リストを与えています。
def test_pass_tuple():
print "---- Pass tuple ----"
seq = (1, 0.5, "Hoge")
code = """
std::cout << "length: " << seq.len() << std::endl;
std::cout << "seq[0]: " << static_cast<int>(seq[0]) << std::endl;
std::cout << "seq[1]: " << static_cast<double>(seq[1]) << std::endl;
std::cout << "seq[2]: " << static_cast<char>(seq[2]) << std::endl;
"""
weave.inline(code, ['seq', ], headers=['<iostream>', ])
数値型や文字列型以外のタプルやリストなどのオブジェクトはSCXXというPython C APIのC++ラッパーライブラリクラスに変換されます。しかし、そのまま使っているわけではなく、weave向けに独自に名前とか書き換えているっぽいです。tuple型はpy::tupleに変換されます。APIは直接weave.__file__の下のscxxフォルダにある*.hファイルを読めばすぐわかります。一応ここ(
http://projects.scipy.org/scipy/browser/trunk/Lib/weave/scxx)でも見れます。py::list::operator[]でタプルの中の要素をpy::object(正確にはindexed_ref型)として取り出すことができます。py::objectには、数値型、str型、complex型の変換演算子が定義されているので、代入やキャストによって中身をCの型として取り出すことができます。---- Pass tuple ---- length: 3 seq[0]: 1 seq[1]: 0.5 seq[2]: Hogeリストの場合もSCXXのpy::listに変換され、APIはほぼ同じです。
def test_pass_list():
print "---- Pass list ----"
seq = [1, 0.5, "Hoge"]
code = """
std::cout << "length: " << seq.len() << std::endl;
std::cout << "seq[0]: " << static_cast<int>(seq[0]) << std::endl;
std::cout << "seq[1]: " << static_cast<double>(seq[1]) << std::endl;
std::cout << "seq[2]: " << static_cast<char>(seq[2]) << std::endl;
"""
weave.inline(code, ['seq', ], headers=['<iostream>', ])
出力は以下
---- Pass list ---- length: 3 seq[0]: 1 seq[1]: 0.5 seq[2]: Hoge辞書型はSCXXのpy::dict型に変換されます。APIも非常に簡単です。
def test_pass_dict():
print "---- Pass dict ----"
dct = {"PyInt":1, "PyFloat":0.5, "PyString":"Hoge"}
code = r"""
std::cout << "length: " << dct.len() << std::endl;
std::cout << "dct[\"PyInt\"]: " << static_cast<int>(dct["PyInt"]) << std::endl;
std::cout << "dct.has_key(\"PyInt\"): " << dct.has_key("PyInt") << std::endl;
std::cout << "dct.has_key(\"PyHoge\"): " << dct.has_key("PyHoge") << std::endl;
py::list keys = dct.keys();
std::cout << "keys[0] : " << static_cast<char>(keys[0]) << std::endl;
py::object tmp = py::object(634);
dct.set_item("SkyTree", tmp);
std::cout << "dct[\"SkyTree\"] : " << static_cast<int>(dct["SkyTree"]) << std::endl;
"""
weave.inline(code, ['dct', ], headers=['<iostream>', ])
出力は以下。
---- Pass dict ----
length: 3
dct["PyInt"]: 1
dct.has_key("PyInt"): 1
dct.has_key("PyHoge"): 0
keys[0] : PyInt
dct["SkyTree"] : 634
例にはないですが、変数は参照として渡されているのでinlineの中で変更したdict型は呼び出し側でも変更されます。sudo apt-get install sqlite3
IPX=$HOME/python27 export PATH=$IPX/bin:$PATH export LD_LIBRARY_PATH=$IPX/lib:$LD_LIBRARY_PATHrootでインストールしてしまう場合は
./configure --prefix=$IPX --enable-shared && make install
sh setuptools-0.6c11-py2.7.egg --prefix=$IPX
$IPX/bin/easy_install pip
$IPX/bin/pip install numpy sudo apt-get install liblapack-dev gfortran g++ $IPX/bin/pip install scipy $IPX/bin/pip install ipython $IPX/bin/pip install virtualenv virtualenvwrapper $IPX/bin/pip install matplotlib再ログインなどするとパスが通っていないので、
IPX=$HOME/python27 export PATH=$IPX/bin:$PATH export LD_LIBRARY_PATH=$IPX/lib:$LD_LIBRARY_PATHを.bashrcなどに追加して常にパスが通っているようにしておく。(rootインストールの場合は必要なし)
sudo apt-get install cmake-curses-gui wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2ダウンロードして解凍。 cmakeに必要なオプションを渡してインストール。
ccmake .. -DCMAKE_INSTALL_PREFIX=${IPX} -DPYTHON_EXECUTABLE=${IPX}/bin/python -DPYTHON_INCLUDE_DIR=${IPX}/include/python2.7 -DPYTHON_LIBRARY=${IPX}/lib/libpython2.7.so
make install
OK。
$ ipython >>> import cv2で使えます。
wget http://cairographics.org/releases/py2cairo-1.8.10.tar.gz tar xvjf py2cairo-1.8.10.tar.gz cd py2cairo-1.8.10 ./waf configure --prefix=$IPX ./waf build ./waf installl
sudo apt-get install libffi-dev http://ftp.gnome.org/pub/GNOME/sources/pygobject/2.21/pygobject-2.21.1.tar.bz2 tar xvjf pygobject-2.21.1.tar.bz2 cd pygobject-2.21.1 ./configure --prefix=$IPX make install
sudo apt-get install libgtk2.0-dev export PKG_CONFIG_PATH=$IPX/lib/pkgconfig:$PKG_CONFIG_PATH wget http://ftp.gnome.org/pub/GNOME/sources/pygtk/2.17/pygtk-2.17.0.tar.bz2 あとはPyGObjectと同じ
from scipy import weave
def test_hello_world():
print "----- Print ----"
code = r"""
printf("Hello world!!\n");
"""
weave.inline(code)
if __name__ == '__main__':
test_hello_world()
Cコードを埋め込むための一つのメソッドがweave.inlineです。上のように、第1引数にCのコードを書いた文字列を取ります。出力は、
----- Print ---- Hello world!!となります。
weave.inline(code, verbose=2, force=True)いろいろverboseされます。
----- Print ---- <weave: compiling> running build_ext running build_src build_src building extension "sc_de155a42ad0378e80d2e4d68a547cce52" sources build_src: building npy-pkg config files customize UnixCCompiler customize UnixCCompiler using build_ext customize UnixCCompiler customize UnixCCompiler using build_ext building 'sc_de155a42ad0378e80d2e4d68a547cce52' extension compiling C++ sources C compiler: c++ -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -I/usr/local/include -DNDEBUG -g -O3 -Wall compile options: '-I/usr/local/lib/python2.7/site-packages/scipy/weave -I/usr/local/lib/python2.7/site-packages/scipy/weave/scxx -I/usr/local/lib/python2.7/site-packages/numpy/core/include -I/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c' c++: /usr/local/lib/python2.7/site-packages/scipy/weave/scxx/weave_imp.cpp c++: /Users/USERNAME/.python27_compiled/sc_de155a42ad0378e80d2e4d68a547cce52.cpp c++ -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -isysroot / -L/usr/local/lib /var/folders/jp/rhc_v7hn46g05j5v678bjbfm0000gn/T/USERNAME/python27_intermediate/compiler_f217358f4c5a874fd8a2d639e1b28c86/Users/USERNAME/.python27_compiled/sc_de155a42ad0378e80d2e4d68a547cce52.o /var/folders/jp/rhc_v7hn46g05j5v678bjbfm0000gn/T/USERNAME/python27_intermediate/compiler_f217358f4c5a874fd8a2d639e1b28c86/usr/local/lib/python2.7/site-packages/scipy/weave/scxx/weave_imp.o -o /Users/USERNAME/.python27_compiled/sc_de155a42ad0378e80d2e4d68a547cce52.so running scons Hello world!!ごちゃごちゃとありますが、
c++: /Users/USERNAME/.python27_compiled/sc_de155a42ad0378e80d2e4d68a547cce52.cppを見るとCコードが生成されている場所がわかります。僕はMac OSX Lionなので、ホームの.python27_compliedにソースコードが自動生成されているのがわかります。Windwosなどでもverbose=2にすれば、どこにソースが生成されたかを知ることができます。このソースを覗いてみるとweaveがどのようにcodeをCコードに変換しているかがわかります(compiled_func関数)。
[*****@*****] $ dpkg -l | grep linux-image rc linux-image-3.2.0-23-generic 3.2.0-23.36 Linux kernel image for version 3.2.0 on 64 bit x86 SMP rc linux-image-3.2.0-25-generic 3.2.0-25.40 Linux kernel image for version 3.2.0 on 64 bit x86 SMP rc linux-image-3.2.0-26-generic 3.2.0-26.41 Linux kernel image for version 3.2.0 on 64 bit x86 SMP ii linux-image-3.2.0-27-generic 3.2.0-27.43 Linux kernel image for version 3.2.0 on 64 bit x86 SMP ii linux-image-3.2.0-29-generic 3.2.0-29.46 Linux kernel image for version 3.2.0 on 64 bit x86 SMP ii linux-image-3.2.0-31-generic 3.2.0-31.50 Linux kernel image for version 3.2.0 on 64 bit x86 SMP iU linux-image-3.2.0-32-generic 3.2.0-32.51 Linux kernel image for version 3.2.0 on 64 bit x86 SMP ii linux-image-generic 3.2.0.31.34 Generic Linux kernel imageいっぱいある。結構たくさんある。なんとなく少しは戻れるように3.2.0-29以前を削除することにする
[****@***] $ sudo apt-get remove linux-image-3.2.0-2{3,5,6,7,9}-generic -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package linux-image-3.2.0-23-generic is not installed, so not removed
Package linux-image-3.2.0-25-generic is not installed, so not removed
Package linux-image-3.2.0-26-generic is not installed, so not removed
The following packages will be REMOVED:
linux-image-3.2.0-27-generic linux-image-3.2.0-29-generic
0 upgraded, 0 newly installed, 2 to remove and 66 not upgraded.
15 not fully installed or removed.
After this operation, 298 MB disk space will be freed.
Setting up ubuntu-keyring (2011.11.21.1) ...
...(略) ...
Processing triggers for initramfs-tools ...
update-initramfs: Generating /boot/initrd.img-3.2.0-32-generic
よくみたら最初の方はrcだった。とりあえず、sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y && sudo apt-get autoremove -yしてOK。df -hするとbootパーティションが半分くらい空いたが、また消すのめんどくさいな。
// コピーなし受け渡し、しかしmatへのアクセスは遅いらしい templatepyublas::numpy_matrix takeAndReturn( pyublas::numpy_matrix mat) { return mat; } // ただ返すだけ template pyublas::numpy_matrix returnNumpyMatrix(int numRow, int numCol) { pyublas::numpy_matrix mat(numRow, numCol, 0); return mat; } // ublasをnumpyに変換して返してくれる template pyublas::numpy_matrix returnUblasMatrixAsNumpyMatrix(int numRow, int numCol) { ublas::matrix mat(numRow, numCol, 0); return mat; } // ublasとして返しても変換テーブルで変換して返してくれる。C++で使っている関数がそのまま使える。 template ublas::matrix returnUblasMatrix(int numRow, int numCol) { ublas::matrix mat(numRow, numCol, 0); return mat; } // ublasにコピーして渡される template void takeUblasMatrix(ublas::matrix mat) { } // コンパイルは通るが、実行時に怒られる template void takeUblasMatrixRef(ublas::matrix &mat) { } // ublasに変換してコピーして渡される template void takeConstUblasMatrix(const ublas::matrix mat) { } // constだと参照でも渡せる。 template void takeConstUblasMatrixRef(const ublas::matrix &mat) { }
tar xvzf PyUblas-VERSION.tar.gz
cd PyUblas-VERSION ./configure.py --boost-python-libname=boost_python --use-iterators sudo make install
cd test
cmake_minimum_required(VERSION 2.8)
find_package(Boost COMPONENTS python REQUIRED)
find_package(PythonLibs REQUIRED)
find_path(PYUBLAS_DIR pyublas /usr/local/lib/python2.7/dist-packages/PyUblas-2011.1-py2.7-linux-x86_64.egg/include)
# 共有オブジェクトを作成する
add_library(
sample_ext
SHARED
sample_ext.cpp
)
# インクルードディレクトリ -Iにあたる
include_directories(
${Boost_INCLUDE_DIRS}
${PYTHON_INCLUDE_DIR}
${PYUBLAS_DIR}
)
# リンクディレクトリ -Lにあたる
link_directories(
${Boost_LIBRARY_DIRS}
)
# リンク -lにあたる。libboost_python.soとlibpython2.7.soが設定されている
target_link_libraries(
sample_ext
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
)
# libsample_extとならないようにする
set_target_properties(
sample_ext
PROPERTIES PREFIX ""
)
mkdir build ccmake ..して見つからなかったところを設定して、(特にPYUBLAS_DIRのところ)
mv sample_ext.so ../ cd .. python sample.py