Using class self in jitclass


@jitclass([('b',float64)])
class A:
    def __init__(self,b):
        self.b=b
    def func(self,a):
        return self.b+a
    def func2(self,a,c):
        return c+self.func(a)
myA=A(1)
myA.func(1,2)

It gives

TypingError: Failed in nopython mode pipeline (step: nopython frontend)

  • Resolution failure for literal arguments:
    too many positional arguments
  • Resolution failure for non-literal arguments:
    None

During: resolving callee type: BoundFunction((, ‘func’) for instance.jitclass.A#7f056bbbb580)
During: typing of call at (3)

How?

Hi @disadone

I don’t think the above works in the Python interpreter either:

from numba.experimental import jitclass
from numba import float64

#@jitclass([('b',float64)])
class A:
    def __init__(self,b):
        self.b=b
    def func(self,a):
        return self.b+a
    def func2(self,a,c):
        return c+self.func(a)

myA=A(1)
myA.func(1,2)

gives:

    myA.func(1,2)
TypeError: func() takes 2 positional arguments but 3 were given

Changing the code so that the call to myA.func() has just one argument, as per the signature, results in it working as expected, e.g.:

from numba.experimental import jitclass
from numba import float64

@jitclass([('b',float64)])
class A:
    def __init__(self,b):
        self.b=b

    def func(self,a):
        return self.b + a

    def func2(self, a, c):
        return c + self.func(a)

myA=A(1)
myA.func(2) # <---- CHANGE IS HERE

hope this helps?

1 Like

I figure out what I want to ask……
It is passing a function to a class method.

@jitclass([('b',float64)])
class A:
    def __init__(self,b):
        self.b=b
    def func(self,dx,a):
        return self.b+a+dx
    def func2(self,a,b,c):
        f=lambda dx:self.func(dx,c)
        return self.integral(f,a,b)
    def integral(self,f,a,b):
        return f(b)-f(a)

myA=A(1)
myA.func2(1,2,1)

The above gives me:

- Resolution failure for literal arguments:
Failed in nopython mode pipeline (step: convert make_function into JIT functions)
Cannot capture the non-constant value associated with variable 'c' in a function that will escape.

File "di12.py", line 13:
    def func2(self, a, b, c):
        f = lambda dx:self.func(dx, c)
        ^

- Resolution failure for non-literal arguments:
None

What it’s saying is that argument c to function f must be compile time constant (c is not constant, it’s a runtime argument to func2) this is because f is going to “escape” (as it’s an argument to return self.integral(f, a, b)) and to do type inference on f, c must be known at compile time.

I get it. Thank you!

a new episode……

from numba import jitclass,float64
@jitclass([('b',float64)])
class A:
    def __init__(self,b):
        self.b=b
    def func(self,dx,a):
        return self.b+a+dx
    def func2(self,a,b):
        f=lambda dx:self.func(dx)
        return self.integral(f,a,b)
    def integral(self,f,a,b):
        return f(b)-f(a)

myA=A(1)
myA.func2(1,2)

TypingError: Failed in nopython mode pipeline (step: nopython frontend)

  • Resolution failure for literal arguments:
    Failed in nopython mode pipeline (step: convert make_function into JIT functions)
    Cannot capture the non-constant value associated with variable ‘self’ in a function that will escape.

File “”, line 9:
def func2(self,a,b):
f=lambda dx:self.func(dx)
^

  • Resolution failure for non-literal arguments:
    None

During: resolving callee type: BoundFunction((, ‘func2’) for instance.jitclass.A#7f531378ffa0)
During: typing of call at (3)

File “”, line 3: