Specifying signature for jitclass method

Anyway to specify jitclass method signatures? For example:

@jitclass
class Test:
	number: float32

	def __init__(self):
		self.number = np.float32(1293.341)

	def calc(self, n: uint64) -> float32:
		return n*self.number

TestType = as_numba_type(Test)

@njit(float32(TestType, uint64))
def Test_calc(self: TestType, n: uint64) -> float32:
	return n*self.number

t = Test()
# will succeed
print(Test_calc(t, 10))
print(Test_calc(t, 18446744073709551615))
# will fail
print(t.calc(10))
print(t.calc(18446744073709551615))

I’ve been thinking of just doing C-style “methods” instead, e.g. the Test_calc function. Works, but not as clean obviously.

Numba’s default integer is int64. Your argument 18446744073709551615 is larger than the maximum value that can be represented. This is also what the error message tells you (kind of):

OverflowError                             Traceback (most recent call last)
g:\My Drive\Private\profile-tools\tests\_cy.ipynb Cell 1 line 2
     26 # will fail
     27 print(t.calc(10))
---> 28 print(t.calc(18446744073709551615))

OverflowError: int too big to convert

Simply pass the argument as an unsigned integer and it should work: t.calc(np.uint64(18446744073709551615))

Test_calc works because you define the signature and therefore Numba does the conversion for you. If you do not pass the signature you will observe the same issue.

1 Like

Yeah I was aware of the numpy workaround. Though I was observing 10-50% overhead in converting all the arguments to numpy types in the interpreter. So was hoping to be able to specify signature for the jitclass method itself, like with Test_calc

This conversion only needs to be done at the Python-Numba interface. If this has a significant impact on the runtime of your program, it suggests to me that there may be bigger design problems. Also keep in mind that you only need to do the explicit conversion to uint64 once. After the first call, the function is compiled and the conversion will be done for you. For example, the following works:

t = Test()
t.calc(nb.uint64(0))
t.calc(18446744073709551615)