2014年3月27日木曜日

簡潔データ構造 (succinct data structure)

最近、簡潔データ構造が気になってる。

きっかけは、2年位前の国立情報学研究所(NII)のオープンハウスに行って、定兼さんの透過的データ圧縮の話を聞いてからだ。すぐにでもOSSとしてライブラリをリリースするという話だったが、2年経っても公開されていない。

なので、ぼちぼちと自分で調べたことや理解したことなどメモしていってみようと思う。


まず、透過的データ圧縮で使う簡潔データ構造とは何か?
G. Jacobson, "Space-efficient Static Trees and Graphs", IEEE 1989が元ネタ。
簡単に言うと、新しいデータ構造。

データ構造には大きく分けて以下の3つがある。
簡潔データ構造 on Wiki

以下は、勘違いが多かったので、修正しました

データTがあり、その情報理論的限界、例えば“-ΣP・log P”をZとすると、
  • Z+O(1)を必要とするデータ構造をimplicit data structure
    例えば、圧縮データをZ、データ長をO(1)だけ保持する構造
  • Z+o(Z)を必要とするデータ構造をsuccinct data strcuture (簡潔データ構造)
    o(Z)はO(Z)未満の何か。つまりZ+Z未満、2Z未満のデータ。
    圧縮した生データ+圧縮したインデックスだと2Zを超える。
    例えば、圧縮したインデックスで元データを展開できるような構造(と理解している)
  • O(Z)を必要とするデータ構造をcompact data structure (コンパクトデータ構造)
    Z+o(Z)以上なので、Z+Z以上の何か。
    例えば、圧縮した生データ+圧縮したインデックスを保持する構造
要は、Inverted Indexなんかの技法がcompact data strcutureで、その次の世代の技法としてsuccinct data structureが実用化されつつあるという話。

このsuccinct data structureの入力をunstructuredデータとし、データ構造の圧縮を頑張ることによって、必要データ量を、Z+o(Z)から極限までZに近づけて、かつ定数時間で展開できるようにすると、上述の透過的データ圧縮となる。というのは勘違いかな。勘違いかも。勘違いだったよう。

提案されている手法は、LZ78の辞書をsuccient data structureに置き換え、定数時間内で展開する方法を提案するという感じでした。succient data structureだけだと高次圧縮できないから、他の手法と組み合わせたほうがいいか。

補足、上ではo(Z)はZ未満の何かといっているが、o(Z)の定義では任意のkについてkO(Z)以下。なのでZ以下の方が意味的には正しいはず。とはいえ、ニュアンス的に、未満の方が説明しやすかったので、上では未満としている。

2014年3月25日火曜日

Ubuntuとgoogle日本語入力とALT+`

先日、google日本語入力を導入した話をした。

導入直後はALT+`が怪しいながらも使えてたのだが、次の日、動作しなくなった。
これを調べて解決したので、その話を書く。

まず、System Settingから、キーボードのショートカットで色々設定できるので、これを調べた。
ところが、ALT+`の設定は存在しない。

google先生に聞くと、CompizConfig Setting Managerで設定するとのこと。
これを導入してみた所、ALT+TABの設定は存在するのだが、ALT+`の設定は存在しない。

google先生にALT+backtickで聞くと、ようやく回答を教えてくれた。

Compizのバグで、Ubuntsu Unity PluginのSwitcherの“Key to fliip through windows in the Switcher”がDisableになっていると、デフォルトキーのALT+`が有効になるらしい。
https://bugs.launchpad.net/unity/+bug/874734

ここに押すことがない適当なキーを登録して、ようやくALT+`が有効になった。
めでたし、めでたし。

HSA enabled gcc

HSAブランチのgccをコンパイルしたので、メモなど。

まずは、コンパイルに必要な物のインストール。
$ sudo apt-get build-dep gcc
そんで、build-depだけではインストールされないflexとbisonのインストール。
$ sudo apt-get install flex bison
HSAブランチのソース取得。
$ svn co svn://gcc.gnu.org/svn/gcc/branches/hsa gcc-hsa
次はコンパイルに必要な、GMPMPFRMPCライブラリをこの順でインストール。
$ wget https://gmplib.org/download/gmp/gmp-5.1.3.tar.lz
$ sudo apt-get install lzip
$ lzip -dc *.lz | tar xfp -
$ cd gmp*/
$ make; make check
$ sudo make install
$ wget http://www.mpfr.org/mpfr-current/mpfr-3.1.2.tar.xz
$ tar xfpJ *.xz
$ cd mpfr*/
$ wget http://www.mpfr.org/mpfr-current/allpatches
$ patch -N -Z -p1 < allpatches
$ make; make check
$ sudo make install
$ wget ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.2.tar.gz
$ tar xfpz *.gz
$ cd mpc*/
$ make; make check
$ make install
途中、mpfrのチェックで、gccで使ってるGMPライブラリと、上でインストールしたGMPライブラリのヘッダのバージョンが違うとか怒られるけど、気にしない方向で。

最後はgccのコンパイル。
$ mkdir gcc-hsa-obj
$ cd gcc-hsa-obj
$ ../gcc-hsa/configure --disable-bootstrap --enable-languages=c,c++ --disable-multilib
試しのコンパイルはこんな感じ。
$ ../gcc-hsa-obj/gcc/xgcc -m32 -B../gcc-hsa-obj/gcc -I/usr/include/x86_64-linux-gnu/ -c ……
HSAILダンプさせてる例もあったのでご参考に。
hsa, gcc hsail + brig

2014年3月24日月曜日

Ubuntuとssh

Ubuntuにsshを入れた。

起動とか手間取ったのでメモなど残す。

sshは適当に入れる。

入れただけではsshdが走らないので、手で立ち上げる。
$ /etc/init.d/ssh start
しかしこれでは起動しないwww
 $ sudo service ssh start
とやらないとダメでした。後は毎回起動するように設定する。
 $ sudo chkconfig ssh on
sudo: chkconfig: command not found
しかしこれでは設定できないwww
 $ sudo update-rc.d ssh defaults
とやらないとダメでした。ナニソレキイテナイヨ……。



Ubuntuとgoogle日本語入力

Ubuntuを入れた。

Wnnとか嫌だなあと検索してみるとgoogle日本語入力が使えるらしい。

「Linux google日本語入力」でgoogle先生に聞いてみると、Linux 快適な日本語入力が出てきた。早速入れてみるが、ibus関係の操作でつまずく。色々試して、ibus-setupじゃなくて、 Text Entry Settingsでやるのだと判明。


こんな感じでmozcを使うよう設定して完了。このあと、Superが押しにくいので、ALT+`で切り替わるよう修正。

その後、13.10から色々変わったのだと判明。
Ubuntu 13.10と日本語入力

2014年3月23日日曜日

2400 メモリ

A10-7850Kを買いました。 

HSAで遊びたいのでメモリも速いのを……、とMBメーカーのメモリリストを調べ、
2400で4枚差しで動いたとあるF3-2400C10D-8GTXを4枚買いました。


ところが……、4枚差すと動かないw

色々やってみたんですが、結論からいうと、諦めて2133で動かすことにしました。
周波数を2133に、他はすべてAutoで、電圧だけ少し落として1.62Vで使います。

以下、同じ悩みの人もいるかもしれないので簡単に思っていることを。


まず、2400で売ってて、メーカーも4枚で動いたって言ってるからと、4枚買うのはまだ駄目みたいです。
じゃあ、どうするか。2枚差しで必要な容量のを買うのが一番です。

その際、A10-7850Kではインターリーブが効果的なのでDual Rankの奴を買いましょう。
Dual Rank 2枚>Single Rank 4枚>Single Rank 2枚の順だそうです。
“Kaveri”はDual-Rankメモリを使用した方が良好な性能を得られる模様


次にA88X-PROの設定などについて。BIOSに入るとEZモードで立ち上がります。
ここでDOCP Profile #1 2401とかいうのを選ぶといいです。Profile #2 2400というのもあります。
メモリタイミングまで一致しており、違いが判りませんでしたw


私は2133で動かしたので、DOCPはDisableにして、Advancedモードで、メモリ速度2133、
他はAutoのままいじらず、電圧だけ1.62と設定しています。

後は、Advanced modeから、CPU設定を選んで、IOMMUをenableにします。
これをしないと、hUMAで動きません。

こんな感じで、やっと動く環境になりました。

2014年3月21日金曜日

popcount

ちょっとわけあってpopcountを調べてた。

以前から、ビットを数える・探すアルゴリズムを参考に

int numofbits5(long bits)
{
    bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
    bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
    bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
    bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
    return (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);
}

とかやってたわけです。この計算の意味は、
  • 1行目で、2ビットずつを足しこみ2ビット単位で1が立っているビット数を計算
  • 2行目は2ビット値×16個を、4ビット値×8個へreduction演算
  • 3行目は4ビット値×8個を、8ビット値×4個へreduction演算
  • 4行目は8ビット値×4個を、16ビット値×2個へreduction演算
  • 5行目は16ビット値×2個を、32ビット値×1個へreduction演算
です。次に、marisa-trie の PopCount を改良しましたを見ると、
explicit PopCount(UInt64 x) : value_() {
    // 格好良いコードにするより,野暮ったいコードの方が速くなりました.
    x = (x & 0x5555555555555555ULL) + ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1);
    x = (x & 0x3333333333333333ULL) + ((x & 0xCCCCCCCCCCCCCCCCULL) >> 2);
    x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x & 0xF0F0F0F0F0F0F0F0ULL) >> 4);

    // x += x << 8; x += x << 16; x += x << 32; とするより高速になりました.
    x *= 0x0101010101010101ULL;

    value_ = x;
}

と4行目5行目を最適化しています。

計算中の値は、4行目の段階で8ビット値になっており、64ビットのpopcountの最大値は64で8ビットに収まります。 そのため、8ビット値×8個を一気に8ビット値×1個へreduction演算できるなら、そのほうが良いわけです。

x *= 0x0101010101010101ULLは、
x = x << 56 + x << 48 + x << 40 + x << 32
    x << 24 + x << 16 + x <<  8 + x <<  0;

を計算しているので、xの上位8ビットに求める値が入っています。

また、1行目は、
  (x & 0x55555555) + (x >> 1 & 0x55555555)
= (x & 0x55555555) + (x >> 1 & 0x55555555) + (x >> 1 & 0x55555555) - (x >> 1 & 0x55555555)
= (x & 0x55555555) + (x & (0x55555555 << 1)) - (x >> 1 & 0x55555555)
= x - (x >> 1 & 0x55555555)

なので最適化でき、3行目も、計算結果の8ビット中の1の数が最大8で4ビットに収まり桁あふれしないので、
  (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f)
= x + (x >> 4) & 0x0f0f0f0f

と最適化できます。最終的に以下のコードとなります。
int numofbits5(unsigned long bits)
{
    bits = bits - (bits >> 1 & 0x55555555);
    bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
    bits = bits + (bits >> 4) & 0x0f0f0f0f;
    bits = bits * 0x01010101;
    return bits >> 24;
}

ここまで考えて、Google先生に聞くと、既出だったw

うう、Blogger先生が勝手に&表記に変換する……。< pre > の中なのに。

2014年3月20日木曜日

Kaveri

さて、気づいたらHSAを実現したA10-7850Kが出荷されてました。

そこで、消費税増税前に一台A10-7850Kマシンを作ることにしました。取り敢えず、MBとしてA88X-PROを選択、メモリも2400の4G×4で16GB用意。明日届くので楽しみだわ。

Aparapiの設定例を参考に、Ubuntuを入れることに決定。