(bind-func main
(let ((domain_size:i32 100)
(max_walk_size:i32 500)
(num_walkers_per_proc:i32 20))
(lambda ()
(MPI_Init null null)
(let ((world_size_ptr:i32* (salloc))
(world_size (begin
(MPI_Comm_size MPI_COMM_WORLD world_size_ptr)
(pref world_size_ptr 0)))
(world_rank_ptr:i32* (salloc))
(world_rank (begin
(MPI_Comm_rank MPI_COMM_WORLD world_rank_ptr)
(pref world_rank_ptr 0)))
(region (decompose_domain domain_size world_rank world_size))
(incoming_walkers (initialize_walkers num_walkers_per_proc max_walk_size region))
(walker_ptr (tref incoming_walkers 1))
(outgoing_walkers (create_walker_array (* num_walkers_per_proc 4)))
;; Determine the maximum amount of sends and receives needed to
;; complete all walkers
(maximum_sends_recvs (+ (/ max_walk_size (/ domain_size world_size)) 1)))
;; (println
;; "Process" world_rank "initiated" num_walkers_per_proc
;; "walkers in subdomain" (tref region 0) " - " (+ (tref region 0)
;; (tref region 1)
;; -1))
(doloop (m maximum_sends_recvs)
(doloop (i (tref incoming_walkers 0))
(walk (walker_at_index incoming_walkers i) region domain_size outgoing_walkers))
;; (println "Process" world_rank "sending" (tref outgoing_walkers 0)
;; "outgoing walkers to process" (% (+ world_rank 1) world_size))
(if (= (% world_rank 2) 0)
(begin
;; Send all outgoing walkers to the next process.
(send_outgoing_walkers outgoing_walkers world_rank world_size)
;; Receive all the new incoming walkers
(receive_incoming_walkers incoming_walkers world_rank world_size))
(begin
;; Receive all the new incoming walkers
(receive_incoming_walkers incoming_walkers world_rank world_size)
;; Send all outgoing walkers to the next process.
(send_outgoing_walkers outgoing_walkers world_rank world_size)))
(println "Process" world_rank "received" (tref incoming_walkers 0)
"incoming walkers"))
(println "Process" world_rank "done.")