아래 코드 예제에서 'obj'및 'ps'라고 표시된 구에 두 세트의 점이 있습니다. '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)
사용하여 속도를 내가 시도
%timeit np.unique(angdist_threshold_numba(vec_obj,vec_ps,cos_maxsep))
1 loops, best of 3: 4.53 s per loop
을하지만이
NotImplementedError: Failed at nopython (nopython frontend)
(<class 'numba.ir.Expr'>, build_list(items=[]))
실패
편집 : numba 업데이트 후 0.26 빈리스트의 생성은 파이썬 모드에서도 실패합니다. 이것은 np.empty (0)로 바꾸고, .extend()를 np.append()로 대체하여 수정할 수 있습니다 (위 참조). 이것은 거의 성능을 변경하지 않습니다. 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가 목록에 문제가있는 것 같기 때문에 스파 스 매트릭스를 대신 사용해 볼 수 있습니까? –