収録日:20201011
発表者:@yohei_kikuta
聞き手:@masa_kazama
内容:
- numpy の nature 論文が出たのでこの機会にちょっと勉強してみるかと思って論文とソースコード(の一部)を読んでみた
- nature 論文の紹介
- 基本的には numpy が科学計算界隈に果たした貢献を称えましょうというタイプの論文
- numpy array の特徴について解説が含まれるが、これは 2011 年の論文の方が詳しく書いてあるので後でそちらで解説
- numpy 以前には Numeric と Numarray という派閥があったが、それを統一して広く参考にされる API を確立してエコシステムを築き上げたのが numpy の偉いところ
- numpy は in-memory で使うものだが、その API は広く参考にされ、遅延評価や分散処理が要求される昨今の DL ライブラリ とか Dask とか CuPy に受け継がれている
__array_function__
protocol で numpy API に基づいてこれらのライブラリを使うことができるようになりつつある
- ありがとう numpy
- なんかこの論文ではやたらと Event Horizon Telescope とか天文系の活用事例にフォーカスして宣伝している
- 余談として 2020 年のノーベル物理学賞の話
- 天文系の話が出たのでついでに話しておく
- Event Horizon Telescope でブラックホールシャドウが観測されたという話とブラックホールに関する Roger Penrose の業績
- 2011 年の The NumPy array: a structure for efficient numerical computation の紹介
- numpy の array の特徴
- データポインタ、データ型記述、shape、strides、フラグ
- numpy の strided memory model
- ゼロコストでの転置や reshape など
- numpy のベクトル化された演算
- ブロードキャストの強力さ
- 演算回数のところは口頭のみの説明だとさすがに伝わりづらいかと思うので、論文の
Creating a grid using broadcasting
を参照のこと
- numpy の array の特徴
- numpy のソースコードリーディング
- 一つの例として
np.sum()
の実装を辿ってみるnumpy/core/fromnumeric.py
からスタートarray_function_dispatch
と NEP-18 の__array_function__
protocol の紹介- C 言語のレイヤーの話と
numpy/core/src/multiarray/calculation.c
のPyArray_Sum
と cpython の話 - 具体的なソースコード実装としての
numpy/core/src/multiarray/einsum.c.src
の話
- 読むの大変で全然何も分からん〜
- 一つの例として
参考情報:
- numpy の nature 論文:https://www.nature.com/articles/s41586-020-2649-2
- The Nobel Prize in Physics 2020:https://www.nobelprize.org/prizes/physics/2020/summary
- Penrose 氏の Wikipedia:https://ja.wikipedia.org/wiki/%E3%83%AD%E3%82%B8%E3%83%A3%E3%83%BC%E3%83%BB%E3%83%9A%E3%83%B3%E3%83%AD%E3%83%BC%E3%82%BA
- Penrose 氏の話しかしてないですが、ノーベル物理学賞の残り 1/2 は銀河中心の supermassive compact object の発見に対するものです
- numpy の 2011 年の論文:https://arxiv.org/abs/1102.1523
- numpy source code:https://github.com/numpy/numpy
- NEP18-A dispatch mechanism for NumPy’s high level array functions:https://numpy.org/neps/nep-0018-array-function-protocol.html
- Einstein の和の規約:https://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%A4%E3%83%B3%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%A4%E3%83%B3%E3%81%AE%E7%B8%AE%E7%B4%84%E8%A8%98%E6%B3%95
- numpy の einsum:https://numpy.org/doc/stable/reference/generated/numpy.einsum.html
numpy の 2011 年の論文の最初の方の話が録音できてなかったのですが、撮り直しが面倒なのでここで補足しておきます。
- numpy の array の構造
- Data Pointer: これは配列の最初の要素のアドレスという話で特に真新しいことはない
- Data type description: 配列のデータ型情報
- Shape: (10, 10) なら 2 次元配列でそれぞれの次元で 10 要素保持しているという情報
- Strides: これが特徴的で次の要素にアクセスするために何バイト飛ばす必要があるかという情報。例えば 1 要素が 8 バイトの (10, 10) という shape の配列がある場合、Strides は (80, 8) になっており、行列的に言えば次の行にアクセスするには 80 バイト飛ばせばよく、次の列にアクセスするには 8 バイト飛ばせばよいことが分かる。
- Flags: 配列を変更可能かを示すフラグで、この attribute をいじれば immutable に変更できたりする。
- source code の型定義は https://github.com/numpy/numpy/blob/master/numpy/core/include/numpy/ndarraytypes.h#L655-L704
その後のゼロコストでの転置や reshape に関しては x = np.arange(9).reshape((3, 3))
という配列の具体例について話をしています。
In [1]: x = np.arange(9).reshape((3, 3))
In [2]: x
Out[2]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [3]: x.strides
Out[3]: (24, 8)