pythonnumbajit

numba jitclass, dictionary of list variables


I need to have dictionary of list variables for jitclass. Following gives me error.

I tried 10 different ways, but did not work. All dictionary values have same length of list.

import numpy as np
import pandas as pd
from numba.experimental import jitclass
from numba import types
import os

os.environ['NUMBA_VERBOSE'] = '1'

spec = [
    ('data', types.Array(types.Record, 1, layout='C'))
]

@jitclass(spec)
class Test:
    def __init__(self, data):
        self.data = data

    def loop(self):
        v = self.data['v']
        v2 = self.data['v2']
        print("Inside loop:")
        print("v:", v)
        print("v2:", v2)

data = [[1, 2, 3], [1.0, 2.0, 3.0]]

# Define the structured array dtype
dtype = np.dtype([
    ('v', np.int64),
    ('v2', np.float64)
])

# Create the structured array
data_array = np.array(data, dtype=dtype)

print("Original data array:")
print(data_array)

# Create an instance of the Test class
test = Test(data_array)
test.loop()

Error:

/home/totaljj/miniconda3/bin/conda run -n bt --no-capture-output python /home/totaljj/bt_lite_strategies/test/test_units/test_numba_obj_Ask.py 
Original data array:
[[(1, 1.) (2, 2.) (3, 3.)]
 [(1, 1.) (2, 2.) (3, 3.)]]
Traceback (most recent call last):
  File "/home/totaljj/bt_lite_strategies/test/test_units/test_numba_obj_Ask.py", line 40, in <module>
    test = Test(data_array)
  File "/home/totaljj/miniconda3/envs/bt/lib/python3.9/site-packages/numba/experimental/jitclass/base.py", line 124, in __call__
    return cls._ctor(*bind.args[1:], **bind.kwargs)
  File "/home/totaljj/miniconda3/envs/bt/lib/python3.9/site-packages/numba/core/dispatcher.py", line 468, in _compile_for_args
    error_rewrite(e, 'typing')
  File "/home/totaljj/miniconda3/envs/bt/lib/python3.9/site-packages/numba/core/dispatcher.py", line 409, in error_rewrite
    raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Internal error at <numba.core.typeinfer.CallConstraint object at 0x7fa912b30a60>.
"Failed in nopython mode pipeline (step: native lowering)\n<class 'numba.core.types.abstract._TypeMetaclass'>"
During: resolving callee type: jitclass.Test#7fa96486ba60<data:array(<class 'numba.core.types.npytypes.Record'>, 1d, C)>
During: typing of call at <string> (3)

Enable logging at debug level for details.

File "<string>", line 3:
<source missing, REPL/exec in use?>

ERROR conda.cli.main_run:execute(124): `conda run python /home/totaljj/bt_lite_strategies/test/test_units/test_numba_obj_Ask.py` failed. (See above for error)

Process finished with exit code 1

Solution

  • The error occurs because types.Record is a generic type without parameters in your code. Actually, it is just a class. You need to instantiate the Record class to define a specialization of the type matching with the one of data in your code. Here is the corrected code:

    import numpy as np
    import pandas as pd
    from numba.experimental import jitclass
    from numba import types
    import os
    
    os.environ['NUMBA_VERBOSE'] = '1'
    
    # ----- BEGINNING OF THE MODIFIED PART ----- #
    recordType = types.Record([
        ('v', {'type': types.int64, 'offset': 0, 'alignment': None, 'title': None}), 
        ('v2', {'type': types.float64, 'offset': 8, 'alignment': None, 'title': None})
    ], 16, False)
    spec = [
        ('data', types.Array(recordType, 2, 'C', False))
    ]
    # -----    END OF THE MODIFIED PART    ----- #
    
    @jitclass(spec)
    class Test:
        def __init__(self, data):
            self.data = data
    
        def loop(self):
            v = self.data['v']
            v2 = self.data['v2']
            print("Inside loop:")
            print("v:", v)
            print("v2:", v2)
    
    data = [[1, 2, 3], [1.0, 2.0, 3.0]]
    
    # Define the structured array dtype
    dtype = np.dtype([
        ('v', np.int64),
        ('v2', np.float64)
    ])
    
    # Create the structured array
    data_array = np.array(data, dtype=dtype)
    
    print("Original data array:")
    print(data_array)
    
    # Create an instance of the Test class
    test = Test(data_array)
    test.loop()