How do I create a jitclass that takes a list of jitclass objects?

I need a jitclass that takes in a list of jitclass instances

import numpy as np
from numba import int64, types
from numba.experimental import jitclass

spec_foo = {"data": int64[:]}


@jitclass(spec_foo)
class Foo(object):
    def __init__(self, init_data):
        self.data = init_data


# Want to have a list of Foo instances in the Bar class
spec_bar = {"foo_list": types.List(Foo.class_type.instance_type, reflected=True)}


@jitclass(spec_bar)
class Bar(object):
    def __init__(self, foo_list):
        # This assigns a reference to a list of Foo instances
        self.foo_list = foo_list


x = np.arange(5).astype(np.int64)
# Build a Foo instance
foo = Foo(x)

# Create a Bar instance that holds a list of Foo instance.
bar = Bar([foo])

This results in the following error:

<string>:3: NumbaPendingDeprecationWarning: 
Encountered the use of a type that is scheduled for deprecation: type 'reflected list' found for argument 'foo_list' of function 'Bar.__init__'.
For more information visit https://numba.pydata.org/numba-doc/latest/reference/deprecation.html#deprecation-of-reflection-for-list-and-set-types
File "test.py", line 20:
class Bar(object):
    def __init__(self, foo_list):
    ^
C:\Users\alujan\anaconda3\envs\quantmacro\lib\site-packages\numba\core\ir_utils.py:2031: NumbaPendingDeprecationWarning: 
Encountered the use of a type that is scheduled for deprecation: type 'reflected list' found for argument 'foo_list' of function 'ctor'.
For more information visit https://numba.pydata.org/numba-doc/latest/reference/deprecation.html#deprecation-of-reflection-for-list-and-set-types
File "<string>", line 2:
<source missing, REPL/exec in use?>
  warnings.warn(NumbaPendingDeprecationWarning(msg, loc=loc))

Any suggestions on how to better do this?

The issue comes from the multiple types of lists in numba: https://numba.pydata.org/numba-doc/dev/reference/pysupported.html#list
To make things more confusing, there’s also several list types: https://github.com/numba/numba/blob/master/numba/core/types/containers.py

Note that the code example above works, and raises the warning. The following code example works and doesn’t raise any warnings. Basically, to use typed.List, you need types.ListType instead of types.List.
This is not unique to jitclass… it’s just that normally if you pass a list to a jit function it will infer the correct types.* given the arguments passed. Jitclass requires you to define your types ahead of time.

import numpy as np
from numba import int64, types, typed
from numba.experimental import jitclass

spec_foo = {"data": int64[:]}


@jitclass(spec_foo)
class Foo(object):
    def __init__(self, init_data):
        self.data = init_data


# Want to have a list of Foo instances in the Bar class
# >>> Use ListType instead of List here.
spec_bar = {"foo_list": types.ListType(Foo.class_type.instance_type)}


@jitclass(spec_bar)
class Bar(object):
    def __init__(self, foo_list):
        # This assigns a reference to a list of Foo instances
        self.foo_list = foo_list


x = np.arange(5).astype(np.int64)
# Build a Foo instance
foo = Foo(x)

# Create a Bar instance that holds a list of Foo instance.
# >>> Pass a typed.List here.
bar = Bar(typed.List([foo]))

With Numba 0.52 you can also simplify the definition of Bar to

import numpy as np
from numba import int64, types, typed
from numba.experimental import jitclass
import typing as pt

spec_foo = {"data": int64[:]}


@jitclass(spec_foo)
class Foo(object):
    def __init__(self, init_data):
        self.data = init_data


@jitclass
class Bar(object):
    # >>> Use new spec syntax. typing.List will be translated to numba.types.ListType.
    foo_list: pt.List[Foo]
        
    def __init__(self, foo_list):
        # This assigns a reference to a list of Foo instances
        self.foo_list = foo_list


x = np.arange(5).astype(np.int64)
# Build a Foo instance
foo = Foo(x)

# Create a Bar instance that holds a list of Foo instance.
bar = Bar(typed.List([foo]))
2 Likes