2019年のまとめ
去年も書いたので今年も書くことにします。あ、年が明けてしまう(´・ω・`)
振り返り
- 1月 お仕事
- 2月 お仕事
- 3月 お仕事
- 4月 お仕事
- 5月 PEZY退職
- 6月 無職
- 7月 RICOS入社
- 8月 お仕事
- 9月 お仕事
- 10月 お仕事
- 11月 お仕事
- 12月 お仕事
5月にPEZYを退職して、7月から計算科学総合研究所(RICOS)さんにお世話になっています。業務内容としては受注のソフトウェア開発と自社開発になります。まだリリース前なので色々は秘密です(´・ω・`)
ソフトウェアの開発に関してはほぼ完全に任せてもらっていて、サービスの設計から実装までやっている感じです。 DockerやKubernetes、Pythonなどの技術的な部分は社内で簡単な講習をしたりしていて、いくつかはQiitaにも上がっています。
勉強会
RICOSで主催している勉強会にいくつか参加するようになりました
微分幾何を最初から勉強していく会です。微分幾何は学部生の頃に解析力学から一般相対論の辺りで勉強し、また理研にいた時に情報幾何的にデータ同化をまとめていた(後述)のもあってある程度なじみがあります。
新しく入社されて谷村氏に情報幾何の話をしてよと言ったらこうなりました。反省しています。
また無職の期間に書き始めたデータ同化の教科書(?)を完成させるための勉強会を始めました
博士時代の乱流の力学系的アプローチで培った知識を基に、データ同化の枠組みを力学系+情報幾何の言葉で書き換える事が目的です。 まだ理研時代のノートの変換も完了していない程度の進捗なので全く進みません。 勉強会はconnpassには公開せずにセミパブリックにやっています。興味ある方はTwitterでDMもらえればslackに参加できます。
OSS
年始にJuliaにハマって色々遊んでみました
Rust + Intel-MKLが Windowsでも動くようにしたり
FlatBuffersの勉強にコンパイラを書いたりしました(未完成)
7月から毎週土曜日にRustオンラインもくもく会を開催して、OSS活動の時間に充てるようにしました。
最初と最後に報告するだけの雑な運営で、たまに寝過ごして居なかったりしましたが(反省しています)、毎回参加してくれているメンバーもいて助かっています。 主にrust-ndarray/ndarray-linalg や rust-math のメンテ時間に充てています。
この年末に accel の再始動を開始したので、来年はこちらへのコミットも増えると思います(希望)
Rust.Tokyo
東京でRustのカンファレンスをやると聞いて応募したら採用してもらえたので、数値計算の現状について発表してきました。
2018年のまとめ
大晦日らしく今年のまとめ記事です。 これは技術記事では無いのでQiitaでなく久しぶり(4年ぶり)にこちらに書きます。
2018年振り返り
- 1月:理研AICS(当時、現R-CCS)を退職
- 2月:内定をもらった社長が逮捕されたので様子見で無職
- 3月:引き続き無職。東京に引越し
- 4月:PEZY Computingに入社
- 5月:お仕事頑張る
- 6月:お仕事頑張る
- 7月:お仕事頑張る
- 8月:お仕事頑張る
- 9月:お仕事頑張る
- 10月:お仕事頑張る
- 11月:お仕事頑張る
- 12月:Advent Calenderにおわれる
博士号を取得して2年弱ほど理研で研究員として働いてきましたが、PEZYに転職してソフトウェアエンジニアになりました。 まだ9ヶ月ほどですが、正直研究者より向いてるように思っています。 主な業務としてはPEZYプロセッサのコンパイラやランタイム、周辺ツールの開発です。 今までは基本的に数値計算のレイヤーやデータの解析、管理のためのコードを書くことが多く、 コンパイラやDMAを行うような領域はあまり経験がなく苦労も多いですが何とかなっています(多分)。
研究者を辞める事には思うところはありましたが、 大学院時代からソフトウェア関係にも進めるようにOSSやQiitaで活動していたり、想定していたプランではあります。
OSS活動
Rust関連のライブラリを主に作ってきました。 理研に居る間に作っていた自分で数値計算用に使うライブラリ群:
- GitHub - termoshtt/ndarray-linalg: Linear algebra package for rust-ndarray using LAPACK binding
- termoshtt / eom · GitLab
はissueには対応していますが、あまり時間が取れずにほとんど放置になっています。実験的に作ったライブラリ
- GitHub - rust-accel/accel: GPGPU Framework for Rust
- GitHub - rust-numpy/rust-numpy: Rust binding of NumPy C-API
については注目されたわりに全然管理出来ておらず、rust-numpyについては@kngwyuが引き継いでくれてPyO3対応等、だいぶ使えるようになってるはずです。 accelについては最近rust-cudaというwork groupが立ち上がったのでそちらに乗っかっていこうと思っています。というかaccelについては年明けのLTで話をするので何かしないとヤバい…
他に今年作ったのは
github.com これはお仕事で必要だったので作りました(PEZYのコンパイラはLLVMベース)
github.com 小さな計算グラフのライブラリです。自動微分の習作のために作りました。これでハミルトン系の計算を行う記事をAdCで投稿しています
github.com RustのSIMD機能が安定したのも今年ですね。Rustでモンテカルロシミュレーションを行おうと思ったときにメルセンヌツイスターの実装が無かったので本家のC実装のSFMTをRustに移植しました
他にもいくつか作ってる気がしますが(自分でも把握してない)、大きいのはこの3つです。
2019年の抱負
- Rustにパッチを投げる
- 数値計算の論文を書く
- 定期的な運動を行う
ソフトウェアエンジニアになりましたが、理論物理の博士としての特色を出したり出さなかったりしていきたいと思います。
Beamerによる発表小技集
LaTeX2e美文書作成入門第6版に Beamer, TikZの章が追加(?:4版にはなかった)されたので、 記念に私のBeamer小技を公開してみる。
初級編
handout
\documentclass[12pt,handout]{beamer}
とすると、\pause
等のアニメーションを考慮しない、
配布用の資料が作れる。
Logo
\logo{\includegraphics[width=1cm]{figure/logo.png}}
プリアンブルに書くと全ページに表示される。
Theme
- 標準のものを紹介: Beamer theme gallery
- Third party製: LaTeX Beamer Themes
お気にいりは標準のこれ:
\usetheme{CambridgeUS}
columns
プレゼンでは良く2行のページを使う:
\begin{columns} \begin{column}{.4\textwidth} ... \end{column} \begin{column}{.6\textwidth} ... \end{column} \end{columns}
column
環境の引数で横幅を指定できる。
block
\begin{block}{定常進行波解} \footnotesize \begin{itemize} \item ... ... \end{itemize} \end{block}
強調して表示してくれる。column
環境の幅を認識してくれる。
これを使用するのと、単なるitemaize
環境だけのだと、
大きく見栄えが異なる。
columns
と組み合わせて使うと便利
\begin{block}{KSEのフィルター方程式} \begin{equation*} ... \end{equation*} \begin{itemize} \item ... \end{itemize} \end{block} \pause \begin{columns} \begin{column}{.45\textwidth} \begin{block}{対称性} ... \end{block} \end{column} \pause \begin{column}{.5\textwidth} \begin{block}{定常進行波解} ... \end{block} \end{column} \end{columns}
上のブロック、左下のブロック、右下のブロックと順に説明する。
単なる\pause
でなく、もう少し複雑な表示の切り替えには
\begin{columns} \begin{column}{.5\textwidth} \begin{block}<1>{span-wisely localized} \begin{figure}[h] ... \end{figure} \end{block} \begin{block}<1-2>{stream-wisely localized} \begin{figure}[h] ... \end{figure} \end{block} \end{column} \begin{column}{.4\textwidth} \begin{block}<1>{wall-normally localized} \begin{figure}[h] ... \end{figure} \end{block} \end{column} \end{columns}
のようにする(1:全部,2:左下のみ)。
table of contents
\frame{\tableofcontents}
\section
, \subsection
で指定されているタイトルを列挙する。
今回の発表の目次的な。
\section{Method} \frame{\tableofcontents[currentsection]}
目次の内、今のセクションだけ強調表示したスライドを挿入する。 上記の場合、Methodが強調される。
vspace, hspace
上手く位置が調整できない時の最終手段。
\vspce{-1cm}
で左に1cm
寄る
応用編
幅を自動取得するbox
\newlength{\bw} \newcommand{\vcbox}[1]{ \settowidth{\bw}{#1} \parbox{\bw}{#1} }
\settowidth
で引数で指定された物 (\includegaphix
とか)のサイズを取得して\bw
に保存。
\parbox
でボックス化する。
TikZ
おまけ程度に:
\begin{tikzpicture}[domain=0:10] ... \end{tikzpicture}
domain
は横軸を決める。
図の左端が0
、右端が10
になる。
長さの定義
\def\distnode{28} \def\righttoleft{27.5}
何度も使う場合。
矢印
\draw[->] (0,0) -- (9,0) node[right] {\scriptsize $x$};
x軸
塗り潰す
\fill[blue!20!white] (0,0) -- (4.5,0) -- (4.5,1) -- (0,1);
色はblue
やwhite
の他に、混合色blue!20!white
(青:80%,白:20%)、
あるいはRGB指定した色
\definecolor{redblack}{rgb}{.4,0,0}
(プリアンブルで定義しておく)が指定可能。
曲線
\draw[variable=\t,domain=0:4] plot ({\t},{-\aL*(\t-\bL)*(\t-\bL)+\cL}) node {};
domain
はvariable
の動く範囲。
曲線で指定された領域を塗り潰す
\fill[fill=white!60!green] (0,0.5) -- plot [variable=\t,domain=0:4.08] ({\t},{-\aLs*(\t-\bLs)*(\t-\bLs)+\cLs}) -- plot [variable=\t,domain=4.93:0] ({\t},{-\aUs*(\t-\bUs)*(\t-\bUs)+\cUs}) -- cycle;
Links
LLVMリンク集
最近何かと話題のLLVM(low-level virtual machine)。 今回はLLVM初心者が、どうしてLLVMが魅力的と思ったか、 幾つかリンクを紹介する形でまとめます。
リンク集
LLVM フレームワークで実用的なコンパイラーを作成する: 第 1 回
早速ですが、紹介記事です。曰く:
LLVM (Low Level Virtual Machine) は、 任意のプログラミング言語で作成されたプログラムを コンパイル時、リンク時、実行時に最適化するために設計された、 極めて強力なコンパイラー・インフラストラクチャー・フレームワークです。 LLVM は多岐に渡るプラットフォームで動作し、 その最大の特徴である、高速に実行されるコードを生成します。
つまりC/C++に限らず、様々な言語で書かれたコードを それぞれのプラットフォームに最適化されたバイナリにコンパイルする事ができます。
コンパイラが存在するDはともかく、 PythonやLuaをネイティブコードに変換できる事は非常に魅力的に思えます。
またGCCをフロントエンドとして使用できるため、GCCでサポートされている
- C
- C++
- Objective-C
- Objective-C++
- Fortran
- Java
- Ada
- Go
で書かれたコードはLLVMの中間表現であるLLVM IRにコンパイルする事ができ、 LLVMの最適化の恩恵を受けられます。 もっともこれらの場合、GCCにより最適化されたバイナリを既に使用できるのですが。
この記事はツール(lli, llvm-config, etc.)の使い方、 LLVM APIによる中間コード(IR)の自動生成までを解説しています。
CUDA LLVM Compiler
nVidiaによるGPGPUのためのフレームワークであるCUDAのコンパイラnvccはLLVMに基づいています。
任意の言語で書いたコードをLLVM IR(正確にはそのサブセットであるNVVM)に変換できれば、 nVidiaの提供するNVVMからPTX(GPU用の低級言語)への変換用バックエンドを用いて GPU上で動作するバイナリを生成する事ができます。
つまりCUDAのような少し特殊な言語を使用せずに、 通常のC/C++をGPU用のコードに変換しうるという事です。 実際にFortranで実行している猛者がいます:
また直接NVVM書いている人もいます:
CUDAだけでなくOpenCLでも同様の取り組み(?)が有る様です:
- LIBCLC: An OpenCL C Library Implementation: (Phoronixの紹介記事)
The LLVM Compiler Infrastructure Project
本家のHPです。ニュースやダウンロードはこちらから確認します。 LLVMは非常に活発に開発されており、
- 2014/01/02 3.4 (最新)
- 2013/07/17 3.3
- 2012/12/20 3.2
- 2012/05/22 3.1
- 2011/12/01 3.0
のようにおよそ半年毎にリリースがあります。
最後に
今後は公式のドキュメントを元に勉強していこうと思います。
vimでひかえめな自動保存
Vim Advent Calendar 2013、 67日目の記事になります。
御存知の通り、 webapi-vimの出現により vimによって簡単にwebサービスを読み書きができるようになりました。 さらにunite.vimや vim-metarwを 使用する事で簡単にインターフェイスを構築できます。
しかし、これらのサービスのAPIの応答は、
一般にローカルに保存する場合に比べ圧倒的に時間がかかります。
さらに現状のvimではajaxのようにスクリプトを非同期実行できない。
もしvim-metarwのwriteで毎回送信する場合、
:w
と押すたびに数秒待たされるかもしれない。
かといって手動で送信するのは忘れがち。
つまりアクセスの回数を絞った自動保存機能が欲しい。
試行錯誤編
という事で試行錯誤が始まります。 多分autocmdにそれっぽいトリガーがあるだろうと思ってhelpを読む事数十分。。。 (あまり読みなれてない)
BufUnload Before unloading a buffer. This is when the text in the buffer is going to be freed. This may be after a BufWritePost and before a BufDelete. Also used for all buffers that are loaded when Vim is going to exit. NOTE: When this autocommand is executed, the current buffer "%" may be different from the buffer being unloaded "<afile>". Don't change to another buffer, it will cause problems. When exiting and v:dying is 2 or more this event is not triggered.
多分これっぽいんだけど、なんか後半に良くわからない事が書いてるorz
めげずに<afile>
について調べると、
<afile> When executing autocommands, is replaced with the file name for a file read or write. <abuf> When executing autocommands, is replaced with the currently effective buffer number (for ":r file" and ":so file" it is the current buffer, the file being read/sourced is not in a buffer).
つまりバッファがアンロードされる時の現在のバッファ(%
)が
トリガーが指定されたバッファ(<abuf>
)と違うかもしれないという事か!!(オウム返し)
:bdelete
で消す場合とか:qa
で全部閉じる場合を考えろってことか。
ともかくこれで行ける!?
<abuf>
はきっとexpand()
使うんだろう:
function! s:buffer_infos() let file_name = expand("<afile>") let buffer_number = expand("<abuf>") let buffer_name = bufname(buffer_number) echo "File name : " . file_name echo "Buffer number: " . buffer_number echo "Buffer name : " . buffer_name let lines = getbufline(buffer_number, 1, '$') echo lines endfunction augroup test_trigger autocmd! autocmd BufUnload test.vim call s:save_buffer_to_file() augroup END
多分これでいけるはず!!
:so %
してバッファを閉じるぜ!!!
File name : test.vim Buffer number: 1 Buffer name : []
(´・ω・`)ショボーン
bufname({expr}) *bufname()* ... If the {expr} is a String, but you want to use it as a buffer number, force it to be a Number by adding zero to it: > :echo bufname("3" + 0) If the buffer doesn't exist, or doesn't have a name, an empty string is returned.
これか?
function! s:buffer_infos() let file_name = expand("<afile>") let buffer_number = expand("<abuf>") let buffer_name = bufname(buffer_number + 0) echo "File name : " . file_name echo "Buffer number: " . buffer_number echo "Buffer name : " . buffer_name let lines = getbufline(buffer_number, 1, '$') echo lines endfunction
File name : test.vim Buffer number: 1 Buffer name : test.vim [ "function! s:buffer_infos()", " let file_name = expand("<afile>")", " let buffer_number = expand("<abuf>")", " let buffer_name = bufname(buffer_number)", " echo "File name : " . file_name", " echo "Buffer number: " . buffer_number", " echo "Buffer name : " . buffer_name", " let lines = getbufline(buffer_number, 1, '$')", " echo lines", "endfunction", "", "augroup test_trigger", " autocmd!", " autocmd BufUnload test.vim call s:save_buffer_to_file()", "augroup END", ]
大勝利!!!
別バッファから:bdelete
しても上手く動く
(`・ω・´)キリッ
まとめ
最終的に
function! s:send(lines) " send data to web service endfunction function! s:wrapper() let buffer_number = expand("<abuf>") let lines = getbufline(buffer_number + 0, 1, '$') call s:send(lines) endfunction augroup ModestAutoSave autocmd! autocmd BufUnload * call s:wrapper() augroup END
とすればいい!パターンの部分は適当に。
おわりに
プラグインとして公開しようと思っていたのですが、 autocmdのパターンの扱い(変数が使えない?)がよくわからなかったので無期限延期しました。 結局すごく短かいですし。
ctestの導入
ctestはcmakeに付随するテスト実行支援ツールである。 Boost TestやCppUnitとは異なり、あくまで実行を支援するツールである。 公式のページを見ると、ダッシュボードを導入しないといけないような印象を受けるが、 cmake管理化のプロジェクトであれば単独で使用できる。
何ができるか?
あなたがcmake管理化のプロジェクトを開発中、 テストを書く必要があるとする。 テストを書く事の重要性は耳にタコができるほど聴いたが、面倒な事は面倒だ。
ともあれ、mylibraryの機能Func1のテストコードtestFunc1.cppを書いたとしよう。 残念ながら、テストコードは自分でかかなければならない。 しかし、テストコードのビルドと実行は手伝う事ができる。 もしあなたが以下に説明する設定を施している場合、 あなたは単にテストコードtestFunc1.cppを含むディレクトリの CMakeLists.txtに以下の一行を追加すればいい。
mytest(Func1 S testFunc1.cpp mylibrary)
よりよいテストのためには次の行さらに前に追加するべきだろう:
set(CMAKE_BUILD_TYPE Debug)
これであなたはそのディレクトリで
make
とすれば、このコードをTEST_Func1_S
にコンパイルする事ができ、
make test
で実行する事ができる。 テストした結果は
Test project /path/to/mylibrary/test Start 1: TEST_Func1_S 1/1 Test #1: TEST_Func1_S ..................... Passed 0.02 sec 100% tests passed, 0 tsets failed out of 1 Total Test time (real) = 0.02 sec
のように表示される。 もちろん実行ファイルをそのままターミナルから実行する事も可能である。
これは現在のディレクトリ以下にあるテストを再帰的に実行するので、 プロジェクトの一番上で実行すれば全てのテストが実行される。 実行ファイルが異常終了した場合にはテストが失敗したと見做され、 まとめて表示される。
これによりコードを変更した際の再テストが
cd $PROJECT_HOME make test
とするだけでよくなる。
使い方
この記事では読者はcmakeの基本的な使い方(add_executable
くらい)を知っているとする。
まず先に私のCMakeLists.txtの抜粋を示す。
enable_testing() add_custom_target(build_test) add_custom_target(short_test COMMAND "ctest" "-R" "TEST_.*_S") add_custom_target(long_test COMMAND "ctest" "-V" "-R" "TEST_.*_L" "2>&1" ">" "long.log" "&") add_dependencies(short_test build_test) macro(mytest name type src libs) set(test_name TEST_${name}_${type}) add_executable(${test_name} ${src}) target_link_libraries(${test_name} ${libs}) add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name}) add_dependencies(build_test ${test_name}) unset(test_name) endmacro(mytest)
やっている事は以下の4つ:
- ctestの有効化
enable_testing()
- targetの追加
build_test
,short_test
,long_test
- 依存関係の追加 (
short_test
depends onbuild_test
) - mytestマクロの定義
ctestの有効化
enable_testing()
これを行なってcmakeを実行すると各ディレクトリにTestingディレクトリが作成される。 ctestを使用するには必須である。
targetの追加
cmakeではshellスクリプトを実行するターゲットを作成する事ができる。
add_custom_target(short_test COMMAND "ctest" "-R" "TEST_.*_S")
によって
make short_test
は依存する物(build_test
)をmakeした後、
ctest -R TEST_.*_S
を実行する。
-R
は名前が正規表現に一致するテストをすべて実行する。
実行ファイル名にS
が付いているのはこのためである。
というのも上述のコードは私の数値計算のコードなので、
一秒以内に終るもの(Sort
)もあれば、数十分かかる物(Long
)もある。
依存関係の追加
make short_test
とした際にbuild_test
がコンパイルされるようにしたのが、
add_dependencies(short_test build_test)
この行である。
さらにbuild_test
が全てのテストに依存するようにしたのが
マクロ中の
add_dependencies(build_test ${test_name})
この行である。 つまり結局
make short_test
とすれば全てのテストがコンパイルされ、実行されるのである。
マクロの定義
macro(mytest name type src libs) set(test_name TEST_${name}_${type}) add_executable(${test_name} ${src}) target_link_libraries(${test_name} ${libs}) add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name}) add_dependencies(build_test ${test_name}) unset(test_name) endmacro(mytest)
さていよいよマクロの定義である。
macro
は最初の引数にマクロの名前を、
以降の引数にマクロの引数を取る。
set
でテスト名を生成し、
add_executable
で実行ファイルを生成する。
肝心なのがadd_test
で、これがテストを定義している。
第一引数がテストの名前、第二引数がテストの実行ファイルである。
この際実行ファイルのパスに注意する。また追加で引数も追加できる。
上述の通りこれをbuild_test
の依存関係に追加する事で、
make short_test
で一気にmakeできる。
何故複雑な依存関係を構築したか?
ここまでで読者は不思議に思ったに違いない: 依存関係を設定しなくても全てのテストがmakeされるのではないかと。 その通りである。 しかし、ある設定をしている場合、そうはならない。
add_subdirectory(test EXCLUDE_FROM_ALL)
がその正体である。
これはtestディレクトリ以下を追加するが、
make
ではtest以下のexecutableはmake
しない、という指示である。
これにより不要なビルドを避ける事で、
ビルド時間を削減するという恩恵が得られる。
上記の設定はこの環境下で行なったための回避策である。
hateblo.vimのmetarw化
pluginのテストのためにこの記事を使用しているため、 情報がおかしい場合があります。 ご注意ください。
hateblo.vimをmetarw化した。
GitHub - termoshtt/hateblo.vim
気にいらなかった挙動は以下の2点
- 記事名のファイルが所構わず作成される
- 新規記事を書き始めにくい
:e hateblo:
で起動する。
コードを読む過程でちょっと書き換えすぎたので、 現在整理中。そのうちpull requestをなげる予定。 refactoring部分とmetarw化の部分を分けてrequestすると思う。
まだ不十分な点が多く、
- New Entryで記事名の入力の際に何も表示されない(入力は成功する)
- 投稿時にwebの応答を待つため、1秒近く止る
はそのうち改善する。
Entryのtitleとcategoryの指定方法を変えた。 この記事を
:e hateblo:{entry_id}
で開くと({entry_id}
は実際には20桁くらいの数値)先頭に、
TITLE:hateblo.vimのmetarw化 CATEGORY:vim
という行が入る。 ここを保存する際に読み込むので、 この行を変更するとタイトルとカテゴリが変更できる。 これならタイトルの入力中に補完が効く。
だいぶ使用できるようになってきた。
投稿した際の遅延だけはどうしようもないのか?