I took a program that makes a mandelbrot plot and made it run on a CPU thread using njit. Now I want to generate a 32k image but even a whole thread is too slow. So I tried to make the code run on a GPU. Here is the code:
from numba import njit, cuda, vectorize
from PIL import Image, ImageDraw
@vectorize(['complex128(complex128)'], target='cuda')
def mandelbrot(c):
z = 0
n = 0
while abs(z) <= 2 and n < 80:
z = z*z + c
n += 1
return n
def vari(WIDTH, HEIGHT, RE_START, RE_END, IM_START, IM_END, draw):
for x in range(0, WIDTH):
for y in range(0, HEIGHT):
print(x)
# Convert pixel coordinate to complex number
c = complex(RE_START + (x / WIDTH) * (RE_END - RE_START),
IM_START + (y / HEIGHT) * (IM_END - IM_START))
# Compute the number of iterations
m = mandelbrot(c)
# The color depends on the number of iterations
color = 255 - int(m * 255 / 80)
# Plot the point
draw.point([x, y], (color, color, color))
def vai():
# Image size (pixels)
WIDTH = 15360
HEIGHT = 8640
# Plot window
RE_START = -2
RE_END = 1
IM_START = -1
IM_END = 1
palette = []
im = Image.new('RGB', (WIDTH, HEIGHT), (0, 0, 0))
draw = ImageDraw.Draw(im)
vari(WIDTH, HEIGHT, RE_START, RE_END, IM_START, IM_END, draw )
im.save('output.png', 'PNG')
vai()
And here is the error:
D:\anaconda\python.exe C:/Users/techguy/PycharmProjects/mandelbrot/main.py
0
Traceback (most recent call last):
File "C:/Users/techguy/PycharmProjects/mandelbrot/main.py", line 56, in <module>
vai()
File "C:/Users/techguy/PycharmProjects/mandelbrot/main.py", line 52, in vai
vari(WIDTH, HEIGHT, RE_START, RE_END, IM_START, IM_END, draw )
File "C:/Users/techguy/PycharmProjects/mandelbrot/main.py", line 30, in vari
m = mandelbrot(c)
File "D:\anaconda\lib\site-packages\numba\cuda\dispatcher.py", line 41, in __call__
return CUDAUFuncMechanism.call(self.functions, args, kws)
File "D:\anaconda\lib\site-packages\numba\np\ufunc\deviceufunc.py", line 301, in call
cr.launch(func, shape[0], stream, devarys)
File "D:\anaconda\lib\site-packages\numba\cuda\dispatcher.py", line 152, in launch
func.forall(count, stream=stream)(*args)
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 372, in __call__
kernel = self.kernel.specialize(*args)
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 881, in specialize
specialization = Dispatcher(self.py_func, [types.void(*argtypes)],
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 808, in __init__
self.compile(sigs[0])
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 935, in compile
kernel.bind()
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 576, in bind
self._func.get()
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 446, in get
ptx = self.ptx.get()
File "D:\anaconda\lib\site-packages\numba\cuda\compiler.py", line 414, in get
arch = nvvm.get_arch_option(*cc)
File "D:\anaconda\lib\site-packages\numba\cuda\cudadrv\nvvm.py", line 345, in get_arch_option
return 'compute_%d%d' % arch
TypeError: not enough arguments for format string
Process finished with exit code 1
If I substitute @vectorize with @njit(nogil=true) it works fine but it runs on CPU. I absolutely need it to run on GPU. I think the problem is something like the complex type.
What is the problem?
The code is not mine: I found it at How to plot the Mandelbrot set .
I just modified some pieces.
Here is a minimal reproducible example:
from numba import cuda, vectorize
@vectorize(['int32(complex128)'], target='cuda')
def mandelbrot(c):
z = 0
n = 0
while abs(z) <= 2 and n < 80:
z = z*z + c
n += 1
return n
comple = complex(10, 12)
print(mandelbrot(comple))
