差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン次のリビジョン両方とも次のリビジョン | ||
programming:python:packages:numba [2020/07/01] – [型を教える] ikatakos | programming:python:packages:numba [2020/07/04] – [引数・戻り値に使える主な型] ikatakos | ||
---|---|---|---|
行 94: | 行 94: | ||
* (*2) Unicode文字列(Python3における通常の文字列) | * (*2) Unicode文字列(Python3における通常の文字列) | ||
* (*2) numba.typed.List, | * (*2) numba.typed.List, | ||
- | * コンパイル済み関数 | + | * コンパイル済み関数(いろいろ制約あり) |
- | * 引数としてのみ使用可 | + | |
- | その他もあるかも知れないけど、どこ見れば書いてあるのかよくわかってない。 | + | その他もあるかも知れない。 |
- | なるべく上の3つのみを使うようにした方がよさそう。(個々の問題点は後述) | + | |
+ | なるべく上の3つのみを使うようにした方がよさそう。 | ||
(*1)はdeprecatedで今後使えなくなる可能性が高い。 | (*1)はdeprecatedで今後使えなくなる可能性が高い。 | ||
行 129: | 行 129: | ||
* [[https:// | * [[https:// | ||
- | どちらも、Pythonのlist機能をNumbaで出来る範囲で表現することを目的としたデータ構造。 | + | どちらも、Pythonのlist機能に似せたようなデータ構造。一応、以下の違いがある。 |
- | * reflected list: Pythonのlistをそのまま受け取ってNumba内で解釈できるようにしたもの | + | * reflected list: 扱い上はPythonのlistのまま、制約を加えてNumbaで解釈できるようにしたもの |
* typed list: Numba独自のリスト構造クラス | * typed list: Numba独自のリスト構造クラス | ||
- | reflected list は deprecated。下記を読むと、ネスト等で複雑になると限界があるので typed listに置きかえていく方針らしい。 | + | reflected listは deprecated。ネスト等で複雑になると限界があるのでtyped listに置きかえていく方針らしい。 |
* [[http:// | * [[http:// | ||
- | そのため、reflected list は(問題なく使えるものの)ver.0.45以降では警告が出る。 | + | そのため、reflected listは(今のところ問題なく使えるものの)ver.0.45以降ではその旨の警告が出る。 |
また、typed listの方は「実験的機能」とされていて、バグがあったり、高速化の恩恵が少なくなる可能性が言及されている。 | また、typed listの方は「実験的機能」とされていて、バグがあったり、高速化の恩恵が少なくなる可能性が言及されている。 | ||
行 149: | 行 149: | ||
* reflected list | * reflected list | ||
- | * 外部から与える際は、ネストは不可。要素の型は統一されている必要がある | + | * 外部から与える際はネスト不可、Numba関数内部で生成する場合はネスト可 |
- | * Numba関数内部では、ネスト可能 | + | * Numba関数内部で「'' |
- | * Numba関数内部で「'' | + | |
* typed.List | * typed.List | ||
* ネスト可 | * ネスト可 | ||
- | * '' | + | * 一度に生成することはできなくて、'' |
また、Pythonのデータ構造にはListの他にSet, | また、Pythonのデータ構造にはListの他にSet, | ||
行 271: | 行 270: | ||
</ | </ | ||
- | ==== グローバル変数 ==== | ||
- | Numba関数内からグローバル変数にアクセスしても、それがNumbaに対応した型なら使える。 | ||
- | |||
- | ただし、AOT や '' | ||
- | |||
- | * [[http:// | ||
- | |||
- | <sxh python> | ||
- | glb = 5 | ||
- | |||
- | @njit(' | ||
- | def global_test(): | ||
- | return glb | ||
- | |||
- | print(global_test()) | ||
- | |||
- | glb = 6 | ||
- | |||
- | print(global_test()) | ||
- | </ | ||
===== 使える関数 ===== | ===== 使える関数 ===== | ||
行 324: | 行 303: | ||
* 意外と(? | * 意外と(? | ||
- | ===== 型を教える ===== | + | |
+ | ===== グローバル変数 ===== | ||
+ | |||
+ | Numba関数内からグローバル変数にアクセスしても、それがNumbaに対応した型なら使える。 | ||
+ | |||
+ | ただし、AOT や '' | ||
+ | |||
+ | * [[http:// | ||
+ | |||
+ | <sxh python> | ||
+ | glb = 5 | ||
+ | |||
+ | @njit(' | ||
+ | def global_test(): | ||
+ | return glb | ||
+ | |||
+ | print(global_test()) | ||
+ | |||
+ | glb = 6 | ||
+ | |||
+ | print(global_test()) | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== 型指定 | ||
'' | '' | ||
行 392: | 行 395: | ||
- | ==== 自動再コンパイル ==== | ||
- | |||
- | Numbaを使用する上で「ソースが変わってなければコンパイル済みのものを使い、更新されていたら再コンパイル」を自動でできると便利。 | ||
- | |||
- | モジュールにコンパイル時のソースコードのファイルハッシュ値を埋め込んで、 | ||
- | 使う時に一致しなければ再コンパイルする、ということが出来ないか試した。 | ||
- | |||
- | しかし、ハッシュ値を得るため一度 '' | ||
- | そのPythonプロセス中は.pydファイルが使用中としてOSに捕まれてしまい、 | ||
- | 再コンパイルにより同名のファイルを作ろうとしても上書きできず途中でエラーになってしまった。 | ||
- | そして明示的に解放する方法が見つからなかった。 | ||
- | ハッシュ値を記録するのをモジュールとは別のテキストファイル等にすると回避できる。 | ||
- | |||
- | 毎回ファイルハッシュを計算するので大きなソースコードには不向きだし、 | ||
- | 自身のファイルしか確認しないため他ファイルの関数を読み込んでいた場合は見逃してしまうが、 | ||
- | そのような制約を把握した上で、単純にコンパイルを必要最小限に出来る。 | ||
- | |||
- | 以下から、メイン関数の中身と、それに与える引数を準備する部分を変更すればよい。 | ||
- | |||
- | <sxh python> | ||
- | import os | ||
- | import sys | ||
- | from hashlib import sha1 | ||
- | |||
- | import numpy as np | ||
- | |||
- | # メイン関数 | ||
- | def solve(inp): | ||
- | a, b, c = inp | ||
- | return a + b + c | ||
- | |||
- | |||
- | def cc_compile(): | ||
- | from numba.pycc import CC | ||
- | |||
- | cc = CC(' | ||
- | cc.export(' | ||
- | cc.compile() | ||
- | print(' | ||
- | |||
- | with open(__file__, | ||
- | file = sha1(rh.read()).hexdigest() | ||
- | with open(' | ||
- | wh.write(file) | ||
- | |||
- | |||
- | if not os.path.exists(' | ||
- | cc_compile() | ||
- | else: | ||
- | with open(__file__, | ||
- | file = sha1(rh.read()).hexdigest() | ||
- | with open(' | ||
- | c_file = rh.read() | ||
- | if file != c_file: | ||
- | cc_compile() | ||
- | |||
- | # noinspection PyUnresolvedReferences | ||
- | from my_module import solve | ||
- | |||
- | # 関数に与える引数準備など | ||
- | inp = np.fromstring(sys.stdin.read(), | ||
- | ans = solve(inp) | ||
- | print(ans) | ||
- | </ | ||