lib: move `examples/mpi` to `lib/mpi/examples`
[nit.git] / lib / mpi / examples / src / mpi_simple.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 module mpi_simple
18
19 import mpi
20
21 # Simple class transfered between processors
22 class ProcessorInfo
23 auto_serializable
24
25 var rank: Int
26 var size: Int
27 var name: String
28 var string_of_random_length: String
29
30 init(mpi: MPI)
31 do
32 self.rank = comm_world.rank.to_i
33 self.size = comm_world.size
34 self.name = mpi.processor_name
35 self.string_of_random_length = "+" * 10.rand
36 end
37
38 redef fun to_s do return "<{name}: {rank}/{size} {string_of_random_length}>"
39 end
40
41 var mpi = new MPI
42
43 var data = new CIntArray(2)
44 if comm_world.size == 1 then
45 print "not enough nodes, got only 1"
46 mpi.finalize
47 exit 1
48 end
49
50 print "stdout: processor '{mpi.processor_name}' {comm_world.rank}/{comm_world.size}"
51
52 if comm_world.rank == 0.rank then
53 # send - ints
54 data[0] = 123
55 data[1] = 456
56 mpi.send_from(data, 0, 2, 1.rank, 0.tag, comm_world)
57
58 # send - simple string
59 mpi.send_all("Hello", 1.rank, 0.tag, comm_world)
60 mpi.send_from(" World", 0, 6, 1.rank, 0.tag, comm_world)
61 mpi.send_from("+-!0?", 2, 2, 1.rank, 0.tag, comm_world)
62 else if comm_world.rank == 1.rank then
63
64 # recv - ints
65 mpi.recv_into(data, 0, 2, 0.rank, 0.tag, comm_world)
66 print "received data: {data[0]} {data[1]}"
67
68 # recv - simple string
69 var buf = new FlatBuffer.with_capacity(5)
70 mpi.recv_fill(buf, 0.rank, 0.tag, comm_world)
71 print "received string: {buf}"
72
73 mpi.recv_into(buf, 5, 6, 0.rank, 0.tag, comm_world)
74 print "received string: {buf}"
75
76 mpi.recv_into(buf, 3, 2, 0.rank, 0.tag, comm_world)
77 print "received string: {buf}"
78 end
79
80 # Passing complex objects and inverse sender/receiver
81 if comm_world.rank == 0.rank then
82 var errors = 0
83 var processors_per_host = new HashMap[String, Int]
84
85 # recv - serializable
86 for p in [1 .. comm_world.size[ do
87 var a = mpi.recv(new Rank.any, 0.tag, comm_world)
88 print "received serialized: {a or else "<null>"}"
89
90 if a != null and a isa ProcessorInfo then
91 if not processors_per_host.keys.has(a.name) then
92 processors_per_host[a.name] = 1
93 else processors_per_host[a.name] += 1
94 else errors += 1
95 end
96
97 print "errors: {errors}"
98 print "processors: {processors_per_host.join(", ", ": ")}"
99 else
100 # send - serializable
101 srand_from comm_world.rank.to_i
102 var a = new ProcessorInfo(mpi)
103 mpi.send(a, 0.rank, 0.tag, comm_world)
104 end
105
106 mpi.finalize