2017-01-25 2 views
4

이 질문의 후속 조치는 function types in numba입니다.생성자 인수

저는 생성기를 인수로 사용해야하는 함수를 작성하고 있습니다. 그것은 발전기의 첫 번째 n 요소의 합계를 반환

def take_and_sum(gen): 
    @numba.jit(nopython=False) 
    def inner(n): 
     s = 0 
     for _ in range(n): 
      s += next(gen) 
     return s 
    return inner 

: 그것은 여기에 붙여, 그래서이 장난감의 예를 고려하는 것이 너무 복잡합니다. 사용 예제 :

내가 nopython=True 컴파일하고 싶습니다 그리고 내가 gen을 통과 할 수 없기 때문에 그것은 카레 것
@numba.njit() 
def odd_numbers(): 
    n = 1 
    while True: 
     yield n 
     n += 2 

take_and_sum(odd_numbers())(3) # prints 9 

(A pyobject) 인수로. 나는 nopython 내 발전기를 컴파일하더라도

TypingError: Failed at nopython (nopython frontend) 
Untyped global name 'gen' 

: 불행하게도, nopython=True에 오류가 발생합니다.

정말로 이것에 대해 혼란은 하드 코딩 입력이 작동한다는 것입니다 :

def take_and_sum(): 
    @numba.njit() 
    def inner(n): 
     gen = odd_numbers() 
     s = 0.0 
     for _ in range(n): 
      s += next(gen) 
     return s 
    return inner 

take_and_sum()(3) 

내가 대신 클래스에 내 발전기를 돌려 시도 :

@numba.jitclass({'n': numba.uint}) 
class Odd: 
    def __init__(self): 
     self.n = 1 
    def next(self): 
     n = self.n 
     self.n += 2 
     return n 

을 다시,이 오브젝트 모드에서 작동 , 그러나 nopython 모드에서 나는 발견 할 수 없다.

LoweringError: Failed at nopython (nopython mode backend) 
Internal error: 
NotImplementedError: instance.jitclass.Odd#4aa9758<n:uint64> as constant unsupported 

답변

2

나는 실제로 sol 수 없다. 내가 아는 바로는 가능하지 않기 때문에 문제를 일으킬 수 있습니다. 난 그냥 (numba 0.30 유효) 일부 측면을 강조하고 있습니다 :

당신 가 numba- jitclass 생성기 만들 수 없습니다 :

import numba 

@numba.jitclass({'n': numba.uint}) 
class Odd: 
    def __init__(self): 
     self.n = 1 

    def __iter__(self): 
     return self 

    def __next__(self): 
     n = self.n 
     self.n += 2 
     return n 

을 그냥 시도 :

>>> next(Odd()) 
TypeError: 'Odd' object is not an iterator 

을 제거하면 numba.jitclass이 작동합니다.

>>> next(Odd()) 
1 

하드 코드 생성기의 예는 동일하지 않습니다. 원래 시도는 생성자 객체를 생성하여 numba 함수에 전달하고 생성자를 수정합니다. 발전기의 상태를 업데이트 할 것으로 예상됩니다.

>>> t = odd_numbers() 
>>> take_and_sum(t)(3) 
9 
>>> next(t) # State has been updated, unfortunatly that requires nopython=False! 
7 

하지만 numba에서는 아직 불가능합니다.당신이 발전기 당신이 함수를 호출 할 때마다 만들 수 있기 때문에

두 번째 예는 다른, 그래서 업데이트해야하는 함수 밖에있는 국가는 없다 :

>>> take_and_sum()(3) # using your hardcoded version 
9.0 
>>> take_and_sum()(3) # no updated state so this returns the same: 
9.0 

는 변경의 definetly 가능 그것은하지만 옵션을 사용하지 않고는 인해 임의 기능을 사용할 수 있습니다 :

@numba.jitclass({'n': numba.uint}) 
class Odd: 
    def __init__(self): 
     self.n = 1 

    def calculate(self, n): 
     s = 0.0 
     for _ in range(n): 
      s += self.n 
      self.n += 2 
     return s 

>>> x = Odd() 
>>> x.calculate(3) 
9.0 
>>> x.calculate(3) 
27.0 

나는 그것이 당신이 원하는 게 아니에요 알고 있지만 적어도 어떻게 든입니다 :-)

012 일
+0

그래, 내 numba 문제의 근본 원인은 로컬이 아닌 변수를 쓰기 가능으로 포착 할 수 없다는 것입니다. – user357269