Last active
January 4, 2025 08:23
-
-
Save terasakisatoshi/66efe858c1196d0378dde3e8d214bbe7 to your computer and use it in GitHub Desktop.
distributed_compute_mandelbrot.jl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Distributed | |
if nworkers() == 1 | |
@info "Start machines..." | |
p = addprocs( | |
[ | |
("username@hostname1", 1), | |
("username@hostname2", 1), | |
("username@hostname3", 1), | |
], | |
dir = "/home/username", # path/to/working/directory/for/workers | |
exename = "/home/username/.juliaup/bin/julia", # path/to/julia | |
exeflags="--threads=auto", | |
) | |
@info "Machines launched!" | |
end | |
@everywhere begin | |
using DistributedArrays, OffsetArrays | |
Base.@kwdef struct Param{I,F} | |
xmin::F = -1.75 | |
xmax::F = 0.75 | |
width::I = 4096 | |
#width::I = 256 | |
ymin::F = -1.25 | |
ymax::F = 1.25 | |
height::I = 4096 | |
#height::I = 256 | |
max_iter::I = 500 | |
end | |
function mandelbrot_kernel(param::Param, c) | |
(; max_iter) = param | |
z = c | |
for i = 0:max_iter-1 | |
z = z * z + c | |
abs(z) > 2 && return i | |
end | |
max_iter | |
end | |
end # everywhere | |
function makeaxes(param::Param) | |
(; xmin, xmax, width, ymin, ymax, height) = param | |
x = range(xmin, xmax, width + 1)[begin:end-1] | |
y = range(ymin, ymax, height + 1)[begin:end-1] | |
x, y | |
end | |
function makeinput(param::Param) | |
x, y = makeaxes(param) | |
complex.(x, y') | |
end | |
function distributed_compute_mandelbrot(param::Param, input) | |
Data = distribute(input) | |
Result = DArray(size(Data)) do inds # local indices on each processor | |
arr = zeros(inds) # We create an OffsetArray with the correct local indices | |
data_local = OffsetArray(localpart(Data), localindices(Data)) # get the local part of data on each processor and assign the proper indices | |
Base.Threads.@threads for i in eachindex(data_local) | |
c = data_local[i] | |
arr[i] = mandelbrot_kernel(param, c) | |
end | |
parent(arr) # strip the OffsetArray wrapper | |
end | |
return Result | |
end | |
using ImageCore | |
using Sixel | |
@info "Setup done" | |
function main() | |
param = Param() | |
inputz = makeinput(param) | |
@time doutput = distributed_compute_mandelbrot(param, inputz) | |
@time output = Matrix(doutput) # gather data in each processor and collect to host machie | |
@assert maximum(output) > 0 | |
normalized = output / maximum(output) | |
gray = colorview(Gray, normalized') | |
sixel_encode(gray) | |
end | |
@info "Run main() manually" | |
if abspath(PROGRAM_FILE) == @__FILE__ | |
main() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
This code calculates the Mandelbrot set using DistributedArrays.jl with multiple nodes (multiple machines).
The base code is based on https://github.com/genkuroki/public/blob/main/0042/mandelbrot%20Julia%201.8.5.ipynb
Result
The following result is derived using 4 x Raspberry Pi 5 = 16 processes.