Reputation: 151
I recently heard about numba, and I wanted to test it out today. I made a simple program which gets the factorial of a number, while timing it.
import time
from numba import jit
@jit()
def fact(args):
x = 1
for i in range(2, args + 1):
x *= i
return x
st = time.time()
x = fact(100000)
print(x)
et = time.time()
elapsed_time = et - st
print("Time elapsed: ", elapsed_time)
For some reason, when the @jit
decorator is present this code only outputs "0", but without numba the code works fine.
Why is this happening and how do I fix this?
Upvotes: 0
Views: 232
Reputation: 2773
import numpy as np
import numba
from numba import jit
from numpy import prod
import time
def factorial(n):
print( prod(range(1,n+1)))
factorial(1)
@jit(nopython=True)
def fact(args):
x = 1
for i in range(2, args + 1):
x *= i
return x
x = 10
st = time.time()
y = fact(x)
print(y)
et = time.time()
elapsed_time = et - st
print("Time elapsed: ", elapsed_time)
1
3628800
Time elapsed: 0.15069580078125
It works great for small values like 10 x = 10 For large values you have to use existing numpy function
@jit()
def factorial1(n):
return(np.math.factorial(n));
st = time.time()
x = factorial1(100)
print(x)
et = time.time()
elapsed_time = et - st
print("Time elapsed: ", elapsed_time)
Upvotes: 1
Reputation: 3649
I believe you may be hitting an issue with numba using native types. Specifically, native int32 values (the most likely culprit) have a limited range whereas Python ints will be as large as needed.
If I add a print statement inside your loop to display x
and run until x
is 0 the output is:
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
1932053504
1278945280
2004310016
2004189184
-288522240
-898433024
109641728
-2102132736
-1195114496
-522715136
862453760
-775946240
2076180480
-1853882368
1484783616
-1375731712
-1241513984
1409286144
738197504
-2147483648
-2147483648
0
As you can see, these all fit inside an int32 and are jumping around all over the place in value.
On the other hand, the output without numba is:
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
403291461126605635584000000
10888869450418352160768000000
304888344611713860501504000000
8841761993739701954543616000000
265252859812191058636308480000000
8222838654177922817725562880000000
263130836933693530167218012160000000
8683317618811886495518194401280000000
295232799039604140847618609643520000000
10333147966386144929666651337523200000000
Taking the 6227020800
line from the Python output, that is
1 0111 0011 0010 1000 1100 1100 0000 0000
in binary. Trimming off the extra bit that won't fit in an int32 gives you 1932053504
, which is exactly what you see in the numba output.
Upvotes: 1