2013年1月11日金曜日

Ubuntu10.04LTSにPython2.7.3をインストール numpy,scipy,matplotlib,opencv,pygtk

ソースからインストールします。全然難しくありません。

sqliteパッケージ使うのに必要だったはず
sudo apt-get install sqlite3

インストール先を指定(ルートインストールしない場合)
IPX=$HOME/python27
export PATH=$IPX/bin:$PATH
export LD_LIBRARY_PATH=$IPX/lib:$LD_LIBRARY_PATH
rootでインストールしてしまう場合は
sudo su -でルートになる。
ルートインストールする場合は--prefixオプションはいらないです。

Python-2.7.3をダウンロードして解凍
./configure --prefix=$IPX --enable-shared && make install

EasyInstallをインストール
サイトから setuptools-0.6c11-py2.7.eggをダウンロード
sh setuptools-0.6c11-py2.7.egg --prefix=$IPX

Pipも
$IPX/bin/easy_install pip

ついでにNumpyやら必要なものをインストール

$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インストールの場合は必要なし)

ついでにOpenCVもインストールする。

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
で使えます。

PyGTKも

依存関係を考慮してシステムのバージョンに合わせる
pygtk 2.17.0
pycairo 1.8.10
pygobject 2.21.1

py2cairoをインストール
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
pygobjectインストール
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
pygtkインストール
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と同じ

2013年1月10日木曜日

Scipy.WeaveでPythonにC++埋め込み 1 Hello world

Pythonって超便利ですね。非常に多様な目的に使われる言語ですが、Numpy・Scipyによる数値計算ライブラリがあるので数値計算・グラフ描画もできます。Matlabなんかもういらないのではないかとおもいますね。しかし、MatlabやPythonのようなインタープリタ言語でループを回したりすると一気に実行速度が激遅になります。そこで、開発者(研究者)はプログラムの高速化が必要な部分をC/C++(以下、C)で書いて呼び出したりします。MatlabではMexによってこれが実現できます。Pythonでもctypes, SWIG, Boost.Python, Cython, Scipy.WeaveによってCによる高速化ができます。今回はWeaveを使った例をお見せします。(Cythonもいずれ紹介します。)

誰もが最初にやるやつ

そう、Hello worldです。WeaveはPythonのコードの中にCコードを直接埋め込むことができます。
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!!
となります。
inlineメソッドは呼び出されたときに第一引数の文字列codeのCコードを実行時コンパイルして呼び出します。これだと呼び出す度にコンパイルが行われ余計に計算時間がかかってしまうと思うかもしれません。しかし実際には、inlineは一度コンパイル済みのものと同じ内容のcodeが渡された時にはコンパイル済みのものを使うため、高速にCコードを呼び出すことができます。 何が起こっているか確認するために、verbose=2と強制的に同じcodeでもコンパイルするためのforce=Trueをオプション引数に追加するように変更してみます。
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関数)。
今回はまったく実用的でないプログラムでしたが、次はweave.inlineに引数を渡す例をお見せします。
変数を渡す編

2012年11月5日月曜日

Mac OSX Lion で Homebrew 経由で Python の pip 使うときに苦労した話

超雑記。

portなどを使っていた環境からbrewへの移行。
portのときどんなふうにインストールしたか記憶がない。
virtualenv, virtualenvwrapperで仮想環境を作っていた。

(Homebrewのインストールは省略。ユーザー権限でインストール。rootじゃない)

brew install python でpython をインストール
.zshenvに
export PATH=/usr/local/bin:/usr/local/share/bin:$PATH
を追加。普通は.bashrc。

同時にインストールされるというpipでnumpyをインストールしようとすると
すでに入っていると言われた

とりあえず pip freezeで得られるパッケージを全削除して
foreach i (`pip freeze | awk -F== '{print $1}'`)
sudo pip uninstall $i
end
(rootでインストールされていたのでsudo)

再度インストール
しかし
/Library/... permission denied
と怒られる。
root権限のところに書こうとしている。前使っていた環境のpipでの書き込み先だ。

brew uinstall python

brew install python --universal
してみた
しかしだめだ

よくよくインストールログを見るとbrew linkが完了しなかったという情報が

brew link python

してみると
pipがすでにあるからリンク貼れなかったぜ馬鹿野郎と怒られる

brew link --overwrite python

して元からあるやつを上書き。
ちゃんと動いた。
前に使っていたpipがpath上に残っていたせいで、そちらのpipの環境を使ってしまっていたのが原因だった。


2012年10月17日水曜日

ubuntu12.04にcuda5.0をインストールしたときに苦労した話

Ubuntu12.04でCUDAでハマったのでメモ。
※CUDAでGPGPU始める人はコレ読んでください。サンプルを見て練習できるので非常に理解がしやすいです。
とにかく、うまく行かなかった。
いろいろ試したが、何が効いたかはわからない。
…が、最終的にうまくいった。

自分の環境はUbuntu12.04 64bit、Dell Precision T5500, Quadro FX 580(capability 1.1)。

とりあえず、最初ココを見て、わけもわからずこのとおりにやった。
http://d.hatena.ne.jp/iRiE/20120620/1340230211
ここでやっている人と明らかに違うのが、Cudaのバージョンが5.0にアップグレードされているというところ。

Ubuntu12.04用のインストーラはないので、11.10のものを代わりに↓からダウンロードした。
http://developer.nvidia.com/cuda/cuda-downloads

sudo sh ./cuda_5.0.35_linux_64_ubuntu11.10.run
を実行すると、libglut.soがないと怒られた。

sudo apt-get install freeglut3-dev
した後、もう一度インストールしてみたが、
やはりないと言われる。

調べてみると、12.04 64bitではlibglut.soが変なところにインストールされることがわかった。

sudo ln -s /usr/lib/x86_64-linux-gnu/libglut.so /usr/lib/libglut.so
してちゃんとしたところにシンボリックリンクを貼る。

再度インストールするもInstall failed、失敗。
ログ見てみると、gdm止めねばならないことが判明。

 自分の場合、Shift+F1でtty1のコンソールを起動して、

sudo service lightdm stop
としてデスクトップマネージャーを止める。(12.04からgdmからlightdmに変わったらしい)

再度チャレンジすると、Installed、成功!

とりあえず、再起動。




デスクトップが起動しないではないか。
そのままtty1に飛ばされる。
ログを見てみると、plymouthに繋げなかったとか言っている。

よくわからないが、ウェブで調べた結果、xserver-xorg-nouveauを消してみたり、nvidia-currentをreinstallしてみたりした。

デスクトップが起動した。

しかし、compizが起動していない。なぜだ。

とりあえず、気にせずCUDAのサンプルをmakeしてコンパイルして、bin/linuz/releaseにいき、

./deviceQuery

したが、capableなビデオカードが見つからないとエラーを出された。
(通常はビデオカードの情報が出力される)

うおーっ!ってなって、

sudo sh ./cuda_5.0.35_linux_64_ubuntu11.10.run --uninstall
でアンインストールして、もう一回インストールしたりしたが、また、デスクトップが起動しなくなった。

最後の方は、記憶がないが、効いたっぽいのが、
http://sn0v.wordpress.com/2012/05/11/installing-cuda-on-ubuntu-12-04/
に書いてある。

sudo apt-get remove --purge nvidia*
によるnvidia関連のソフトウェアの全削除。

これやったあとに、

sudo sh ./cuda_5.0.35_linux_64_ubuntu11.10.run
でCUDAドライバのインストールをやり直したら、Compizも復活して、

./deviceQuery
でちゃんと結果が出力された。


どれが良かったか、わからないがこの中のどれかであるはず。

あと、「追加のドライバ(Additional driver)」から適当にExperimentalの一番新しいっぽいやつをインストールしたりもしたな…

Ubuntuでbootを逼迫している古いLinuxカーネルを削除

慣習に従って/bootディレクトリのパーティションを分けていたら(確か100M)、カーネルの更新のたびに、カーネルイメージがインストールされて、それが残って、/bootパーティションを逼迫していた。dist-upgradeができない状態に。
古いカーネルは不要なので削除する。ちなみに、Ubuntuのバージョンは12.04です。
インストールされているカーネルを確認する。

[*****@*****] $ 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パーティションが半分くらい空いたが、また消すのめんどくさいな。
調べてみると、今の時代ではbootを別パーティションにする必要はないっぽい。
 参考:https://forums.ubuntulinux.jp/viewtopic.php?pid=12939

2012年10月16日火曜日

pyublasのメモ(vector、matrixの受け渡し)

受け渡しに関するメモ

ublas型でも受け渡しができるので便利、ただし、参照型はconstでしか受け取れない。
// コピーなし受け渡し、しかしmatへのアクセスは遅いらしい
template
pyublas::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)
{
}

pyublas使うまでのメモ

環境はUbuntu12.04、Boostはインストール済みとする。ちなみに1.46

まずはPyUblasのインストール
ここから最新版をダウンロード http://pypi.python.org/pypi/PyUblas
tar xvzf PyUblas-VERSION.tar.gz
解凍して
cd PyUblas-VERSION
./configure.py --boost-python-libname=boost_python --use-iterators
sudo make install

boost-python-libnameは/usr/libにあるlibboost_python*.soのlibと.soを除いた部分を設定。
今回はCMakeでサンプルをビルドしてみた。別にMakeでもよい
cd test
すると
sample_ext.cppとsample.pyがある
自分で考えろという意味なのか、Makefileとかがない。
調べると必要なものは
Include: boost, python, pyublas
Library: boost_python, python
で、自分の環境では、
Include:
/usr/local/lib/python2.7/dist-packages/PyUblas-ほげほげ/include
/usr/lib/python2.7
Library:
/usr/lib/libboost_python.so
/usr/lib/libpython2.7.so
にあった

ちなみに、PyUblasのIncludeパスはhttp://documen.tician.de/pyublas/faq.html#where-do-the-headers-get-installedを参考に見つけた。

これを元に、Makefileを作っても良いが、楽をするために、CMakeでやった。

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 ""
)

パッケージが見つからなかったときの処理とかは書いていない。
これをCMakeLists.txtというファイル名でsample_ext.cppと同じディレクトリにおいて、
そこから
mkdir build
ccmake ..
して見つからなかったところを設定して、(特にPYUBLAS_DIRのところ)
ジェネレートして、makeして、OKだったら
mv sample_ext.so ../
cd ..
python sample.py

2倍されている結果が帰ってくる