import cython
# !pip install cython
def fib_min(n):
a, b = 0, 1
while a < n:
a, b = b, a+b
return a
%time len(str(fib_min(10**300_000))
import sys
sys.set_int_max_str_digits(500_000)
%load_ext cython
%%cython -a
def fib_min_compile(n):
a, b = 0, 1
while a < n:
a, b = b, a+b
return a
%time len(str(fib_min_compile(10**300_000))
import cython
def primes(nb_primes: cython.int):
i: cython.int
p: cython.int[10000]
if nb_primes > 10000:
nb_primes = 10000
if not cython.compiled: # Only if regular Python is running
print('NOT COMPILED')
p = [0] * 10000 # Make p work almost like a C array
len_p: cython.int = 0 # The current number of elements in p.
n: cython.int = 2
while len_p < nb_primes:
# Is n prime?
for i in p[:len_p]:
if n % i == 0:
break
# If no break occurred in the loop, we have a prime.
else:
p[len_p] = n
len_p += 1
n += 1
# Let's copy the result into a Python list:
result_as_list = [prime for prime in p[:len_p]]
return result_as_list
%time len(primes(10000))
%%cython -a
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = [15, 5]
plt.rcParams['figure.dpi'] = 100
from numba import jit, vectorize, guvectorize, float64, complex64, int32, float32
def mandelbrot_set(xmin,xmax,ymin,ymax,width,height,maxiter, mandelbrot_func, real=False):
r1 = np.linspace(xmin, xmax, width)
r2 = np.linspace(ymin, ymax, height)
if real:
return [[mandelbrot_func(r, i, maxiter) for r in r1] for i in r2]
return [[mandelbrot_func(complex(r, i), maxiter) for r in r1] for i in r2]
male_hodnoty = (-2.0,0.5,-1.25,1.25,1000,1000,80)
velke_hodnoty = (-0.74877,-0.74872,0.06505,0.06510,1000,1000,2048)
def pds_zobraz(f, real=False):
%time plt.subplot(1, 2, 1).imshow(mandelbrot_set(*male_hodnoty, f, real))
%time plt.subplot(1, 2, 2).imshow(mandelbrot_set(*velke_hodnoty, f, real))
def mandelbrot_python(z,maxiter):
c = z
for n in range(maxiter):
if abs(z) > 2:
return n
z = z*z + c
return maxiter
jit
¶from numba import jit
@jit(nopython=True)
def mandelbrot_numba(z,maxiter):
c = z
for n in range(maxiter):
if abs(z) > 2:
return n
z = z*z + c
return maxiter
@jit(nopython=True)
def mandelbrot_numba_nocomplex(real, imag, maxiter):
c_real, c_imag = real, imag
for n in range(maxiter):
real2 = real*real
imag2 = imag*imag
if real2+imag2 > 4:
return n
real, imag = real2-imag2+c_real, 2*real*imag+c_imag
return maxiter
@jit(nopython=True)
def mandelbrot_numba_nosqrt(z,maxiter):
c = z
for n in range(maxiter):
if z.real*z.real+z.imag*z.imag > 4:
return n
z = z*z + c
return maxiter
@jit(nopython=True)
def mandelbrot_numba_nocomplex(real, imag, maxiter):
c_real, c_imag = real, imag
for n in range(maxiter):
real2 = real*real
imag2 = imag*imag
if real2+imag2 > 4:
return n
real, imag = real2-imag2+c_real, 2*real*imag+c_imag
return maxiter
guvectorize
¶@jit(int32(complex64, int32))
def mandelbrot_compute(c,maxiter):
r = c.real
i = c.imag
for n in range(maxiter):
r2 = r*r
i2 = i*i
if r2 + i2 > 4.0:
return n
i = 2*r*i+c.imag
r = r2-i2+c.real
return maxiter
@guvectorize([(complex64[:], int32, int32[:])], '(n),()->(n)',target='parallel')
def mandelbrot_numpy(c, maxiter, output):
for i in range(c.shape[0]):
output[i] = mandelbrot_compute(c[i], maxiter)
def mandelbrot_set2(xmin,xmax,ymin,ymax,width,height,maxiter):
r1 = np.linspace(xmin, xmax, width, dtype=np.float32)
r2 = np.linspace(ymin, ymax, height, dtype=np.float32)
c = r1 + r2[:,None]*1j
return mandelbrot_numpy(c,maxiter)
def pds_zobraz2(f, real=False):
%time plt.subplot(1, 2, 1).imshow(mandelbrot_set2(*male_hodnoty))
%time plt.subplot(1, 2, 2).imshow(mandelbrot_set2(*velke_hodnoty))
cuda
¶%%time
import numpy as np
from numba import cuda
from numba import *
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = [15, 5]
plt.rcParams['figure.dpi'] = 100
@jit
def mandel(real, imag, max_iters):
cr = real
ci = imag
for n in range(max_iters):
real2 = real*real
imag2 = imag*imag
if real2 + imag2 > 4.0:
return n
imag = 2*real*imag+ci
real = real2-imag2+cr
return max_iters
mandel_gpu = cuda.jit(uint32(float32, float32, uint32), device=True)(mandel)
@cuda.jit((float32, float32, float32, float32, uint32[:,:], uint32))
def mandel_kernel(min_x, max_x, min_y, max_y, image, iters):
height = image.shape[0]
width = image.shape[1]
pixel_size_x = (max_x - min_x) / width
pixel_size_y = (max_y - min_y) / height
startX, startY = cuda.grid(2)
gridX = cuda.gridDim.x * cuda.blockDim.x;
gridY = cuda.gridDim.y * cuda.blockDim.y;
for x in range(startX, width, gridX):
real = min_x + x * pixel_size_x
for y in range(startY, height, gridY):
imag = min_y + y * pixel_size_y
image[y][x] = mandel_gpu(real, imag, iters)
gimage = np.zeros((1000, 1000), dtype = np.uint32)
blockdim = (32, 8)
griddim = (32,16)
d_image = cuda.to_device(gimage)
mandel_kernel[griddim, blockdim](-2.0, 1.0, -1.0, 1.0, d_image, 20)
d_image.copy_to_host(gimage)
plt.subplot(1, 2, 1).imshow(gimage)
d_image = cuda.to_device(gimage)
mandel_kernel[griddim, blockdim](-0.74877,-0.74872,0.06505,0.06510, d_image, 2048)
d_image.copy_to_host(gimage)
plt.subplot(1, 2, 2).imshow(gimage)
parallel
& nogil
¶import time
import numpy as np
import numba
SIZE = 600_000_000
a = np.full(SIZE, 1, dtype = np.int32)
b = np.full(SIZE, 1, dtype = np.int32)
c = np.ndarray(SIZE, dtype = np.int32)
def add_python(a, b, c):
for i in range(SIZE):
c[i] = a[i] + b[i]
def run(func):
print(func.__name__, ':')
start = time.time()
%time func(a, b, c)
end = time.time()
print(f'{end - start:0.5f} s')
run(add_python)
#@numba.jit(nopython = True, parallel = False, nogil = False)
#def add_numba(a, b, c):
# for i in range(SIZE):
# c[i] = a[i] + b[i]
add_numba = numba.jit(add_python, nopython = True, parallel = False, nogil = False)
run(add_numba)
#TYPES
add_numba = numba.jit(add_python, ["none(int32[:], int32[:], int32[:])"], nopython = True, parallel = False, nogil = False)