9

I'm trying to use numba to boost the python performance of scipy.integrate.odeint. To this end, I have to use @nb.jit(nopython=True) for the function defining the ODE system. However, this function has to take another python-class instance as an argument in my program. I had to jit the class also with @nb.jitclass(spec) with appropriate specs. This worked fine, until I found a serious issue when the specs of the class includes another type of class instance as its method. My code is following.

import numba as nb
from scipy.integrate import odeint


spec1=[("hi", nb.i4)]
@nb.jitclass(spec1)
class Hi(object):
    def __init__(self):
        self.hi = 0

spec2=[("dummy", nb.i4), ("dummy1", nb.i4)]
@nb.jitclass(spec2)
class Dummy(object):
    def __init__(self, anotherClassInstance):
        self.dummy = 0
        self.dummy1 = anotherClassInstance

class A:
    def __init__(self, someClassInstance):
        self.a1 = someClassInstance

    def odeSystem(self, x, t):
        return _odeSystem(x, t, self.a1)

    def odeSolve(self, iValues, ts):
        sol = odeint(self.odeSystem, iValues, ts)
        return sol

@nb.jit(nopython=True)
def _odeSystem(x, t, someClassInstance):
    return 1-x



if __name__ == "__main__":
    c = Hi()
    b = Dummy(c)
    a = A(b)
    print a.odeSolve(0.5, range(0, 10))

In summary: So here "class A" is my ode solver.

  1. To compile the method "odeSystem" with numba, it must not a class method. So I made another function outside of the class "_odeSystem".

  2. Unfortunately however, my odeSystem has to have a class instance as an argument. Hence I used @jitclass to compile the class instance argument properly.

  3. I again encountered another problem, where this class "Dummy" also takes another type of class instance as one of its attribute. I have no idea how to set "spec" for this class. I tried the type for "dummy1" with "nb.typeof(Hi)" but it didn't work.

Please help me. Thanks in advance.

hopeso
  • 155
  • 6
  • Welcome to SO! Please be more specific what *serious issue* you encountered and what does *not work* mean? (Expected vs. actual result, error messages, etc.). – MB-F Dec 06 '17 at 06:49
  • @kazemakase Hi, sorry for my vague sentences. It was supposed to mean that the "spec" argument for "@jitclass(spec)" is not clear when I want to set a class instance as an attribute of the current class. In my code, "dummy1" of the class "Dummy" is a type of class instance object. So what should I set for "dummy1" in "spec2"? Now I just set it as ("dummy1", nb.i4) but clearly this is not an int type. So when I run this file, it ended up with a long error saying – hopeso Dec 06 '17 at 15:37
  • a long error saying "[1] During: lowering "(self).dummy1 = anotherClassInstance" at test.py(16) [2] During: resolving callee type: jitclass.Dummy#25a0a20 [3] During: typing of call at (3) – hopeso Dec 06 '17 at 15:37
  • Can you edit your updates into the question? This will make them more readable and it will bump the question, increasing the chance that someone who knows the answer can see it. – MB-F Dec 06 '17 at 15:48

1 Answers1

12

You can use .class_type.instance_type in your spec definition for holding an instance of another type. See example in the numba source tree here

spec2=[("dummy", nb.i4), ("dummy1", Hi.class_type.instance_type)]
@nb.jitclass(spec2)
class Dummy(object):
    def __init__(self, anotherClassInstance):
        self.dummy = 0
        self.dummy1 = anotherClassInstance
chrisb
  • 49,833
  • 8
  • 70
  • 70