2018年5月27日日曜日

Linuxターミナルの色設定

はじめに


Linuxのターミナルの色設定が変わってしまった場合の対処方法についてメモしておきます。 Debian 8.10環境を前提にしています。

環境変数TERM


環境変数TERMに設定することで色設定を変更できます。例えば、
$ TERM=xterm-256color
とします。

なお、xterm-256colorの代わりにscreen-256colorを使うと、lessの検索時にヒットした文字列が斜体(イタリック)になり、ひじょーに見にくくなります。

TERMに設定できる値一覧


TERMに設定できる値は、
$ infocmp -D
で表示されるディレクトリ以下にあるファイル名です。

$ infocmp xterm-256color
のように、TERMに指定できる値を引数に指定することで、内部の設定を表示できます。読み方がわかりませんが…。2個指定すると2つの設定の差分が表示されます。

byobu経由


byobu経由でTERMがおかしくなるときは、手動でTERMを設定するか、byobuの設定を変更します。 tmuxバックエンドの場合は、~/.config/byobu/.tmux.conf に
set-option -g default-terminal xterm-256color
set -g terminal-overrides 'xterm:colors=256'
を追記します。もしかすると2行目は不要かもしれません。 ~/.byobu 以下にも設定ファイルがあるかもしれませんが、有効なほうを変更します。

参考


https://unix.stackexchange.com/questions/179173/make-less-highlight-search-patterns-instead-of-italicizing-them
https://www.tldp.org/HOWTO/Text-Terminal-HOWTO-16.html

追記(2018/9/8)


byobuの起動前後でターミナルの色が異なる場合は、
byobu-disable-prompt
を実行しましょう。byobuの色設定が使われなくなります。逆に、byobuの設定を使いたい場合は、
byobu-enable-prompt
を実行します。

2018年5月4日金曜日

PythonとC++間でのnumpy配列の受け渡し

はじめに


Pythonで作ったnumpy.ndarrayをC++側で加工して、Pythonに返す方法を試します。

PythonからCの関数を呼び出す方法は色々あるようですが、 今回は、numpyを操作したいので、Boost C++ Librariesを使ってみます。

準備


Boost C++ Librariesをインストールします。
https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html
の第1節に従ってダウンロードし、第5節に従ってビルドします。

方法(動的リンク版)


まず、C++のコードです。ファイル名は test1.cpp とします。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <boost/python/numpy.hpp>
namespace p = boost::python;
namespace np = boost::python::numpy;

void plus_scalar(np::ndarray &a, float b)
{
  auto N = a.shape(0);
  auto *p = reinterpret_cast<float*>(a.get_data());
  for(auto v=p; v!=p+N; ++v){*v=*v+b;}
}

BOOST_PYTHON_MODULE(test1)
{
  Py_Initialize();
  np::initialize();
  p::def("plus_scalar", plus_scalar);
}
Python側から第1引数で渡される1次元NumPy配列に第2引数で渡される値を足すだけの関数plus_scalarを定義しています。

このtest1.cppをコンパイルします($はシェルのプロンプトです)。

$ g++ --std=c++14 --shared -fPIC -I$BOOST_PATH/include/ -I/usr/include/python2.7/ test1.cpp -L$BOOST_PATH/lib -lboost_numpy27 -lboost_python27 -o test1.so
$BOOST_PATHはBoost C++ Librariesをインストールしたパスです。

ライブラリのパスが通っていないので、

$ export LD_LIBRARY_PATH=$BOOST_PATH/lib
を実行し、.soをロードできるようにしておきます。

これをPythonから呼び出します。次のようにPythonスクリプト t1.py を作成します。

1
2
3
4
5
6
7
8
9
import sys
sys.path.append('.')
import test1
import numpy as np

a = np.array([1,2,3], dtype=np.float32)
print(a)
test1.plus_scalar(a, 3.0)
print(a)

そして、実行します。

python t1.py
すると、
[ 1.  2.  3.]
[ 4.  5.  6.]
が出力されます。確かに、3.0が足されています。

方法(静的リンク版)


動的リンク版では LD_LIBRARY_PATH を設定しましたが、使いにくいのでBoost関連のライブラリだけでも静的リンクしておきましょう。次のようにすることで.soを作ることができます。
g++ --std=c++14 --shared -fPIC -I$BOOST_PATH/include/ -I/usr/include/python2.7/ test2.cpp $BOOST_PATH/lib/libboost_numpy27.a $BOOST_PATH/lib/libboost_python27.a -o test2.so

もし、次のエラー

/usr/bin/ld: $BOOST_PATH/lib/libboost_numpy27.a(ndarray.o): 再配置 R_X86_64_32 (`.rodata.str1.8' に対する) は共有オブジェクト作成時には使用できません。-fPIC を付けて再コンパイルしてください。
$BOOST_PATH/lib/libboost_numpy27.a: error adding symbols: 不正な値です
collect2: error: ld returned 1 exit status
が出て、リンクできないときは、エラーメッセージの通りにBoostをビルドし直します。 具体的には、[4]を参考に、
$ ./b2 --clear
$ ./b2 cxxflags=-fPIC cflags=-fPIC install
のように、cxxflagsを追加してビルドし直します。cflagsは不要かもしれません。なお、ここで追加したオプション名は、--cxxflagsでも、-cxxflagsでもなく、ハイフン無しの単なるcxxflagsです。

test2.cppは

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <boost/python/numpy.hpp>

namespace p = boost::python;
namespace np = boost::python::numpy;

void plus_scalar(np::ndarray &a, float b)
{
  auto N = a.shape(0);
  auto *p = reinterpret_cast<float*>(a.get_data());
  for(auto v=p; v!=p+N; ++v){*v=*v+b;}
}

BOOST_PYTHON_MODULE(test2)
{
  Py_Initialize();
  np::initialize();
  p::def("plus_scalar", plus_scalar);
}
t2.pyは
1
2
3
4
5
6
7
8
9
import sys
sys.path.append('.')
import test2
import numpy as np

a = np.array([1,2,3], dtype=np.float32)
print(a)
test2.plus_scalar(a, 3.0)
print(a)
です。test1がtest2に変わっただけです。
$ python t2.py
を実行すると、動的リンク版のときと同様に
[ 1.  2.  3.]
[ 4.  5.  6.]
と出力されます。

参考


[1] http://d.hatena.ne.jp/nihohi/20120306/1331002942
[2] http://tadaoyamaoka.hatenablog.com/entry/2017/05/25/234934
[3] https://stackoverflow.com/questions/10968309/how-to-import-python-module-from-so-file
[4] https://stackoverflow.com/questions/27848105/how-to-force-compilation-of-boost-to-use-fpic