私は球面上に以下のコード例で 'obj'と 'ps'という2つの点集合を持っています。私は 'ps'点から特定の角度距離より近いすべての 'obj'点を特定したいと思います。Numbaによるナンシー最適化
これは、各点を3D単位ベクトルで表し、そのドット積をcos(最大分離)と比較することです。これはnumpy放送では簡単に行うことができますが、私のアプリケーションではn_obj〜500,000とn_ps〜50,000があり、放送のメモリ要件が大きすぎます。以下は、numbaを使って私の現在のテイクを貼り付けたものです。これはさらに最適化できますか?
from numba import jit
import numpy as np
from sklearn.preprocessing import normalize
def gen_points(n):
"""
generate random 3D unit vectors (not uniform, but irrelevant here)
"""
vec = 2*np.random.rand(n,3)-1.
vec_norm = normalize(vec)
return vec_norm
#@jit(nopython=True)
@jit
def angdist_threshold_numba(vec_obj,vec_ps,cos_maxsep):
"""
finds obj that are closer than maxsep to a ps
"""
nps = len(vec_ps)
nobj = len(vec_obj)
#closeobj_all = []
closeobj_all = np.empty(0)
dotprod = np.empty(nobj)
a = np.arange(nobj)
for ps in range(nps):
np.sum(vec_obj*vec_ps[ps],axis=1,out=dotprod)
#closeobj_all.extend(a[dotprod > cos_maxsep])
closeobj_all = np.append(closeobj_all, a[dotprod > cos_maxsep])
return closeobj_all
vec_obj = gen_points(50000) #in reality ~500,000
vec_ps = gen_points(5000) #in reality ~50,000
cos_maxsep = np.cos(0.003)
closeobj_all = np.unique(angdist_threshold_numba(vec_obj,vec_ps,cos_maxsep))
これは、コード内で与えられたテストケースを使用してパフォーマンスです:私は
@jit(nopython=True)
を使用してそれをスピードアップしようとしているが、これは
NotImplementedError: Failed at nopython (nopython frontend)
(<class 'numba.ir.Expr'>, build_list(items=[]))
で失敗
%timeit np.unique(angdist_threshold_numba(vec_obj,vec_ps,cos_maxsep))
1 loops, best of 3: 4.53 s per loop
編集:numbaを0.26に更新した後空リストの作成はPythonモードでも失敗します。これは、np.empty(0)で置換し、np.append()で.extend()を置き換えることで修正できます。これはほとんどの場合、パフォーマンスを変更しません。 https://github.com/numba/numba/issues/858 np.empty()によると
は今nopythonモードでサポートされていますが、私はまだ(= nopython true)を@jitでこれを実行することはできません。
TypingError: Internal error at <numba.typeinfer.CallConstraint object at 0x7ff3114a9310>
はあなただけ使用することはできませんscipy.spatial.distanceからのcdist?すなわち、 distance.cdist(vec_obj、vec_ps、 'cosine') –
これは高速で、必要な処理を行います。しかし、私がこの例で使った数字では、cdistが返した2D配列は〜2GBのメモリを使います。つまり、実際のサイズ(両方の軸に沿って10倍大きくなります)を使用すると、メモリの問題が再び発生します。 – user4319496
あなたはカスタムルートに行くのが正当だと思われます。 numbaはリストに問題があるようですので、スパース行列を代わりに使用できますか? –