t

メモ

An Bug of AsyncExecutor of Slick

既にうろ覚えだが Slick 3.3.0 で取り込まれた "critical bug in AsyncExecutor #1856" の修正についてメモしておく。

AsyncExecutor の内部状態がおかしくなるのが #1856 で起きていたことで、これは PrioritizedRunnable が持つ DB への既存の接続を閉じたかを表すフラグの誤操作により引き起こされていた。そして誤操作の原因は一つの StreamingContext を(意図しないタイミングで)二つの PrioritizedRunnable から触っていたことだった。PrioritizedRunnable を実行する AsyncExecutor のバグというより PrioritizedRunnable を作成する DatabaseDef のバグと言えるかもしれない。

#1856 で報告されていた症状は怪しいスタックトレースが出力される(が当該スレッドは元々終了しようとしていたものなので一見動作に支障はない)というものだが、AsyncExecutor の内部状態がおかしくなっているので他の問題も起こしていた可能性はありそう。

修正は #1914 で行った。フラグを操作する場所を変えて、余計なフラグ設定が行われないようにしている。

XGBoost4J with OpenMP on macOS

macOSGCC 7 を使って OpenMP 有効な XGBoost4J 0.7 のビルドをしても、そのままだとテストでこける。以下が問題のようだ。

ロケール

こんな感じの落ち方をする。

  thread #71, stop reason = signal SIGSTOP
    frame #0: 0x00007fff57534e3e libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff57673150 libsystem_pthread.dylib`pthread_kill + 333
    frame #2: 0x00007fff57491312 libsystem_c.dylib`abort + 127
    frame #3: 0x000000010968ccf3 libjvm.dylib`os::abort(bool) + 25
    frame #4: 0x00000001097b4646 libjvm.dylib`VMError::report_and_die() + 2304
    frame #5: 0x000000010968e91e libjvm.dylib`JVM_handle_bsd_signal + 1131
    frame #6: 0x000000010968ab83 libjvm.dylib`signalHandler(int, __siginfo*, void*) + 47
    frame #7: 0x00007fff57666f5a libsystem_platform.dylib`_sigtramp + 26
    frame #8: 0x00007fff57467bad libsystem_c.dylib`__numeric_load_locale + 568
    frame #9: 0x00007fff57469a68 libsystem_c.dylib`loadlocale + 212
    frame #10: 0x000000012abba17c libxgboost4j.dylib`std::__convert_from_v((null)=<unavailable>, __out=":", __size=<unavailable>, __fmt="%.*f") at c++locale.h:67
    frame #11: 0x000000012abc1a32 libxgboost4j.dylib`std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(this=0x000000012ace3800, __s=<unavailable>, __io=0x000070000ca85600, __fill=<unavailable>, __mod=<unavailable>, __v=0) const at locale_facets.tcc:1005
    frame #12: 0x000000012abcd7ad libxgboost4j.dylib`std::ostream& std::ostream::_M_insert<double>(this=0x000070000ca85590, __v=0) at locale_facets.h:2434
    frame #13: 0x000000012aa2dc3a libxgboost4j.dylib`xgboost::LearnerImpl::EvalOneIter(int, std::vector<xgboost::DMatrix*, std::allocator<xgboost::DMatrix*> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) + 538
    frame #14: 0x000000012a9b470d libxgboost4j.dylib`XGBoosterEvalOneIter + 541
    frame #15: 0x000000012a9a1640 libxgboost4j.dylib`Java_ml_dmlc_xgboost4j_java_XGBoostJNI_XGBoosterEvalOneIter + 1168

手元の環境では __convert_from_v の定義は /usr/local/opt/gcc/include/c++/7.3.0/x86_64-apple-darwin17.3.0/bits/c++locale.h にあり、LC_NUMERICC でなかったら C にして後で元に戻す、という実装になっていた。

このパスに入る箇所を調べて別実装に置き換えてまわるのも面倒そうだったので export LC_NUMERIC=C として回避した。

そういえば P0067R5: Elementary string conversions, revision 5 を見たら Existing approaches が全てロケール依存のようでちょっと驚いた。

シグナル

pthread がシグナルハンドラを触るからだと思う。libxgboost4j より先に libjsig をロードしておくことで回避できた。

select()

socket()FD_SETSIZE より大きい値を返すことがある。そのためアサーションにひっかかる。アサーションというよりは select() の仕様が問題となっていそう。select() の代わりに kqueue() を使うように実装を書き換えたら回避できた、と思う。

追記: 0.81 において select()poll() に置き換える形で直されたと思われる

Jupyter Scala + coursier-s3

Jupyter Scalacoursier-s3 をくっつけてみた。最初は coursier 側coursier-s3 側 の両方で URL.setURLStreamHandlerFactory の呼び出しが必要な気がしたが、この場合は後者は不要なようで、結局 jupyter-scala依存に coursier-s3 を加えるだけで済んだ。

github.com

実際に Jupyter の kernel として登録するにはチェックアウトして以下を実行すれば良い。

$ sbt publishLocal
$ VERSION=0.3.0-SNAPSHOT project/generate-launcher.sh -s
$ ./jupyter-scala

.s3credentials の置き場所は fm-sbt-s3-resolver と共通にしたければ ~/.sbt の下、別にしたければ ~/.coursier の下が良さそう。

GFM to HTML w/ Syntax Highlighting

ディレクトリ内の GitHub Flavored Markdownシンタックスハイライトしつつ HTML に変換して回りたかった。が、上手い方法が分からなかった。が、次のようにすれば変換できないこともないのでそれで良いことにした。

$ pip install Pygments
$ pip install markdown2
$ find . -type f -name '*.md' -print0 | while read -r -d '' file; do { echo '<head><meta charset="UTF-8"><link rel="stylesheet" href="https://rawgit.com/richleland/pygments-css/master/github.css"><link rel="stylesheet" href="https://rawgit.com/sindresorhus/github-markdown-css/gh-pages/github-markdown.css"></head><body class="markdown-body">'; markdown2 --extra fenced-code-blocks "$file"; echo '</body>' } > "${file%%.md}.html"; done