I'm seeking a way to modify a jitclass
variable with its name as a string. I tried to write a setter and getter function (get_A
and set_A
), and I got the method outside the jitclass
. I would like then to pass that method to a jitclass
method to update the value of the variable. However I get and error saying:
numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
non-precise type pyobject
[1] During: typing of argument at <string> (3)
File "<string>", line 3:
<source missing, REPL/exec in use?>
This error may have been caused by the following argument(s):
- argument 1: cannot determine Numba type of <class 'tuple'>
Here the minimal example:
from numba import float64
from numba.experimental import jitclass
spec = [('A', float64), ('B', float64), ('C', float64)]
@jitclass(spec)
class maClass:
def __init__(self):
self.A = 0
def get_A(self):
return self.A
def set_A(self, x):
self.A = x
def update(self, func, val):
func(val)
C1 = maClass()
print('A', C1.A)
Names= ['A']
vals= [1.]
func = getattr(C1, 'set_' + Names[0])
print(func)
C1.update(func, vals[0])
print('A', C1.A)
Here is a solution I came up with. I first wrote a function that return a list of the variable names I can update
def get_Variable_Names():
return ['A','B','C']
then, in the jitclass, I wrote a function that can update variable according to an index based on the order of get_Variable_Names
.
def update_val(self, i, var):
if i == 0:
self.A = var
elif i == 1:
self.B = var
elif i == 2:
self.C = var
To use this function, I search for the index of a variable name in the list returned by get_Variable_Names
and then call the update_val
function of the jitclass.
listnames = get_Variable_Names()
val = 1.
name = 'A'
index = listnames.index(name)
C1.update_val(index,val)
here's all the code.
from numba import jitclass, int32, float64
def get_Variable_Names():
return ['A','B','C']
spec = [('A' ,float64),('B' ,float64),('C' ,float64)]
@jitclass(spec)
class maClass():
def __init__(self,):
self.A = 0.
self.B = 0.
self.C = 0.
def update_val(self, i, var):
if i == 0:
self.A = var
elif i == 1:
self.B = var
elif i == 2:
self.C = var
C1 = maClass()
listnames = get_Variable_Names()
val = 1.
name = 'A'
index = listnames.index(name)
C1.update_val(index,val)
val = 2.
name = 'B'
index = listnames.index(name)
C1.update_val(index,val)
val = 3.
name = 'C'
index = listnames.index(name)
C1.update_val(index,val)
print('A',C1.A)
print('B',C1.B)
print('C',C1.C)
It is not was I was looking for, but it is find for now.
I'm still waiting for something better.
I even wrote a script to write the if else update_val function, because It can be tedious when we have a large amount of variables to modify
listnames= ['A','B','C']
for i, n in enumerate(listnames):
if i == 0:
print('if i == ' + str(i)+ ' :\n\tself.' + n + ' = var')
else:
print('elif i == ' + str(i) + ' :\n\tself.' + n + ' = var')