Skip to content

Commit 75e6f86

Browse files
committed
"Ray mandelbrot"
1 parent a043387 commit 75e6f86

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

examples/ray/mandelbrot.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from charm4py import ray, charm
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
import os
5+
6+
# Compute whether a point is in the Mandelbrot set
7+
def mandelbrot_fast(re, im, max_iter):
8+
zr = zi = 0.0
9+
for i in range(max_iter):
10+
zr2 = zr * zr
11+
zi2 = zi * zi
12+
if zr2 + zi2 > 4.0:
13+
return i
14+
zi = 2 * zr * zi + im
15+
zr = zr2 - zi2 + re
16+
return max_iter
17+
18+
# Remote task to compute a tile
19+
@ray.remote
20+
def compute_tile(x_start, x_end, y_start, y_end, width, height, max_iter):
21+
tile = np.zeros((y_end - y_start, x_end - x_start), dtype=np.uint16)
22+
for y in range(y_start, y_end):
23+
for x in range(x_start, x_end):
24+
re = 3.5 * (x / width) - 2.5
25+
im = 2.0 * (y / height) - 1.0
26+
tile[y - y_start, x - x_start] = mandelbrot_fast(re, im, max_iter)
27+
return tile
28+
29+
def generate_mandelbrot_image_optimized(width=12000, height=8000, max_iter=200, tile_size=1000, max_pending=1000):
30+
# Pre-create the empty file with the correct size
31+
total_bytes = 2 * width * height # 2 bytes per pixel (uint16)
32+
with open("output/mandelbrot_large.dat", "wb") as f:
33+
f.seek(total_bytes - 1)
34+
f.write(b'\0')
35+
result_image = np.memmap("output/mandelbrot_large.dat", dtype=np.uint16, mode='w+', shape=(height, width))
36+
pending = []
37+
38+
for y in range(0, height, tile_size):
39+
for x in range(0, width, tile_size):
40+
x_end = min(x + tile_size, width)
41+
y_end = min(y + tile_size, height)
42+
tile_ref = compute_tile.remote(x, x_end, y, y_end, width, height, max_iter)
43+
pending.append(((x, y), tile_ref))
44+
45+
if len(pending) >= max_pending:
46+
(x0, y0), tile = pending.pop(0)
47+
tile = ray.get(tile)
48+
result_image[y0:y0+tile.shape[0], x0:x0+tile.shape[1]] = tile
49+
50+
for (x0, y0), tile_ref in pending:
51+
tile = ray.get(tile_ref)
52+
result_image[y0:y0+tile.shape[0], x0:x0+tile.shape[1]] = tile
53+
54+
return result_image
55+
56+
57+
def main(args):
58+
output_path = "output/mandelbrot_large.dat"
59+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
60+
ray.init()
61+
# Run the benchmark
62+
image = generate_mandelbrot_image_optimized(width=int(args[1]), height=int(args[2]), max_iter=int(args[3]), tile_size=int(args[4]))
63+
# Optional: show the result
64+
plt.imshow(image, cmap='hot')
65+
plt.title("Mandelbrot Set (Ray)")
66+
plt.axis('off')
67+
plt.savefig("mandelbrot_ray.png", dpi=300, bbox_inches='tight')
68+
os.remove('output/mandelbrot_large.dat')
69+
charm.exit()
70+
71+
charm.start(main)

0 commit comments

Comments
 (0)