File: pi.rb

package info (click to toggle)
ruby-mpi 0.4.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 408 kB
  • sloc: ansic: 1,500; ruby: 808; makefile: 8
file content (59 lines) | stat: -rw-r--r-- 1,139 bytes parent folder | download
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
# Run this program using
#
# mpirun -np 2 ruby pi.rb numpoints
#
# where numpoints is an integer
# 
# The program is based on an example from
# https://carpentries-incubator.github.io/hpc-intro/16-parallel/index.html

require "mpi"
if defined?(NumRu::NArray)
  include NumRu
end

def inside_circle my_count
  x = NArray.float(my_count).random
  y = NArray.float(my_count).random
  a = ((x**2 + y**2) < 1.0)
  return a.count_true
end

MPI.Init

world = MPI::Comm::WORLD

size = world.size
rank = world.rank

def usage(rank)
 if rank==0
   print <<EOF
Usage: mpirun -np numproc ruby #$0 numpoints
       numpoints must be an integer > 0
EOF
 end
  MPI.Finalize
  exit -1
end
usage(rank) if ARGV.length != 1
usage(rank) if ( ( /^\d+$/ =~ ARGV[0] ) != 0)
n_samples = ARGV[0].to_i
usage(rank) unless n_samples > 0

my_samples = n_samples.div(size) 
if ( n_samples % size > rank  ) 
  my_samples = my_samples + 1
end

my_count = NArray[0]
count = NArray[0]

my_count[0] = inside_circle my_samples 

world.Reduce(my_count,count,MPI::Op::SUM,0)
if ( rank == 0 )
  p "Pi is approximately " + ((count[0]*4.0)/(1.0*n_samples)).to_s
end

MPI.Finalize