I’m relatively new to Numba, so I’m not sure if I’m doing something wrong.
I’d been tinkering with some simpler math functions, trying out using numba’s @njit on them, which was interesting. Then out of curiosity, I figured I’d try it on a generator function which outputs digits of pi, just to see how fast it could go…
Normally this script works fine, outputs the correct digits, even colors 0-9 differently for fun. However, adding the @njit decorator to the function causes it to only output 0s. (I’m on Python 3.8.10, numba 0.56.0, numpy 1.22.4)
from numba import njit
@njit
def calcPi(n):
"function from: https://gist.github.com/deeplook/4947835"
k, a, b, a1, b1 = 2, 4, 1, 12, 4
while n > 0:
p, q, k = k * k, 2 * k + 1, k + 1
a, b, a1, b1 = a1, b1, p * a + q * a1, p * b + q * b1
d, d1 = a / b, a1 / b1
while d == d1 and n > 0:
yield int(d)
n -= 1
a, a1 = 10 * (a % b), 10 * (a1 % b1)
d, d1 = a / b, a1 / b1
colors = ('\033[90m','\033[37m','\033[36m','\033[96m','\033[94m','\033[32m','\033[93m','\033[31m','\033[91m','\033[95m')
pi_digits = calcPi(1000000)
lastDigit = 0
try:
for d in pi_digits:
print(colors[d] + str(d), end='', flush=True)
lastDigit += 1
except KeyboardInterrupt:
print("\n\033[0mDigits calculated:", lastDigit)
If I comment out all the math in the calcPi function, and replace it with a simple addition-counter that cycles through 1-9, outputting those as the digits, that works fine with numba…
I’ve even tried swapping out that pi function for an alternate one, which uses a slightly different formula, and while that is able to output the first 5 digits accurately, after that it crashes with an error, cause the formula starts spitting out weird -1 values or something… So I assume either I’m just missing something simple, or I’ve run into some bug/limitation that prevents calculating pi, for some reason?
314150-1-11Traceback (most recent call last):
File "calcpi_alt.py", line 32, in <module>
print(colors[d] + str(d), end='', flush=True)
IndexError: tuple index out of range
@njit
def calcPi():
q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
while True:
if 4*q+r-t < n*t:
yield n
nr = 10*(r-n*t)
n = ((10*(3*q+r))//t)-10*n
q *= 10
r = nr
else:
nr = (2*q+r)*l
nn = (q*(7*k)+2+(r*l))//(t*l)
q *= k
t *= l
l += 2
k += 1
n = nn
r = nr