-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpi_monte_carlo_co_sum.f90
66 lines (55 loc) · 2.28 KB
/
pi_monte_carlo_co_sum.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
! Computes an approximation of Pi with a Monte Carlo algorithm
! Co_sum with final results
! Vincent Magnin, 2021-04-22
! and Brad Richardson
! Last modification: 2024-09-03
! MIT license
! $ caf -Wall -Wextra -std=f2018 -pedantic -O3 m_xoroshiro128plus.f90 pi_monte_carlo_co_sum.f90
! $ cafrun -n 4 ./a.out
! or with ifx :
! $ ifx -O3 -coarray m_xoroshiro128plus.f90 pi_monte_carlo_co_sum.f90
program pi_monte_carlo_co_sum
use, intrinsic :: iso_fortran_env, only: wp=>real64, int64
use m_xoroshiro128plus
implicit none
type(rng_t) :: rng ! xoroshiro128+ pseudo-random number generator
real(wp) :: x, y ! Coordinates of a point
integer(int64) :: n ! Total number of points
integer(int64) :: k ! Points into the quarter disk
integer(int64) :: i ! Loop counter
integer(int64) :: n_per_image ! Number of parallel images
integer :: t1, t2 ! Clock ticks
real :: count_rate ! Clock ticks per second
n = 1000000000
k = 0
! Each image have its own RNG seed, thanks to rng%jump() which
! generates non-overlapping subsequences for parallel computations:
call rng%seed([ -1337_i8, 9812374_i8 ])
if (this_image() /= 1) then
do i = 2, this_image()
call rng%jump()
end do
end if
x = rng%U01()
call system_clock(t1, count_rate)
n_per_image = n / num_images()
write(*, '(a, i3, a, i3)', advance='no') "Image ", this_image(), "/", num_images()
write(*, '(a, i11, a)') " will compute", n_per_image, " points"
do i = 1, n_per_image
! Computing a random point (x,y) into the square 0<=x<1, 0<=y<1:
x = rng%U01()
y = rng%U01()
! Is it in the quarter disk (R=1, center=origin) ?
if ((x**2 + y**2) < 1.0_wp) k = k + 1
end do
! At the end:
call co_sum(k, result_image = 1)
if (this_image() == 1) then
write(*,*)
write(*, '(a, i0, a, i0)', advance='no') "4 * ", k, " / ", n
write(*, '(a, f17.15)') " = ", (4.0_wp * k) / n
call system_clock(t2)
write(*,'(a, f6.3, a)') "Execution time: ", (t2 - t1) / count_rate, " s"
write(*,'(a)') "---------------------------------------------------"
end if
end program pi_monte_carlo_co_sum