source: project/wiki/eggref/4/mpi @ 33441

Last change on this file since 33441 was 33441, checked in by Ivan Raikov, 4 years ago

mpi doc typo fixes

File size: 18.6 KB
Line 
1[[tags:egg]]
2== mpi
3
4Message Passing Interface (MPI)
5
6[[toc:]]
7
8== Usage
9
10(require-extension mpi)
11
12== Documentation
13
14[[http://www.mpi-forum.org/|MPI]] is a popular standard for
15distributed-memory parallel programming. It offers both point-to-point
16message passing and group communication operations (broadcast,
17scatter/gather, etc).
18
19[[http://www.open-mpi.org/|Open MPI]] is an implementation of the MPI
20standard that combines technologies and resources from several other
21projects (FT-MPI, LA-MPI, LAM/MPI, and PACX-MPI) in order to build the
22best MPI library available.
23
24The Chicken MPI egg provides a Scheme interface to a large subset of
25the MPI 1.2 procedures for communication.  It is based on the
26[[http://forge.ocamlcore.org/projects/ocamlmpi/|Ocaml MPI]]
27library by Xavier Leroy. The {{mpi}} library has been tested with Open
28MPI versions 1.2.4 - 1.10.1.
29
30=== Initialization and time procedures
31
32
33<procedure>MPI:init :: [ARG1 ...] -> UNDEFINED</procedure>
34
35Initializes the MPI execution environment. This routine must be called
36before any other MPI routine. MPI can be initialized at most once.
37
38
39
40<procedure>MPI:spawn :: COMMAND * ARGUMENTS * MAXPROCS * LOCATIONS * ROOT * COMM -> (COMM * S32VECTOR)</procedure>
41
42Spawns {{MAXPROCS}} identical copies of the MPI program specified by
43{{COMMAND}} and returns an intercommunicator and a vector of status
44values. {{ARGUMENTS}} is a list of command-line
45arguments. {{LOCATIONS}} is a list of string pairs {{(HOST * WDIR)}}
46that tell MPI the host and working directory where to start processes.
47
48<procedure>MPI:finalize</procedure>
49
50Terminates the MPI execution environment.
51
52<procedure>MPI:wtime :: VOID -> SECONDS</procedure>
53
54Returns the number of seconds representing elapsed wall-clock time on
55the calling process.
56
57
58=== Handling of communicators
59
60
61<procedure>MPI:comm? :: OBJ -> BOOL</procedure>
62
63Returns true if {{OBJ}} is an MPI communicator object, false otherwise.
64
65<procedure>MPI:get-comm-world:: VOID -> COMM</procedure>
66
67Returns the default communicator created by {{MPI_Init}}; the group
68associated with this communicator contains all processes.
69
70<procedure>MPI:comm-size :: COMM -> INTEGER</procedure>
71
72Returns the size of the group associated with communicator {{COMM}}.
73
74
75<procedure>MPI:comm-rank :: COMM -> INTEGER</procedure>
76
77Returns the rank of the calling process in communicator {{COMM}}.
78
79
80<procedure>MPI:comm-equal? :: COMM1 * COMM2 -> BOOL</procedure>
81
82Returns true if the two given communicators are for identical groups, false otherwise.
83
84
85<procedure>MPI:comm-split :: COMM * COLOR * KEY -> COMM</procedure>
86
87Creates new communicators based on colors and keys.
88
89
90<procedure>MPI:comm-create :: COMM * GROUP -> COMM</procedure>
91
92Creates a new communicator with communication group that spans all
93processes in {{GROUP}} and a new context. See the procedures in
94subsection ''Handling of communication groups'' for information on how
95to create process group objects.
96
97
98
99<procedure>MPI:make-cart :: COMM * DIMS * PERIODS * REORDER -> COMM</procedure>
100
101Creates a new communicator with Cartesian topology
102information. Argument {{DIMS}} is an SRFI-4 s32vector that contains
103the number of dimensions of the Cartesian grid. Argument {{PERIODS}}
104is an SRFI-4 s32vector of the same length as {{DIMS}} that indicates
105if the grid is periodic (1) or not (0) in each dimension. Argument
106{{REORDER}} is a boolean value that indicates whether process ranking
107may be reordered.
108
109
110
111<procedure>MPI:make-dims :: NNODES * NDIMS -> DIMS</procedure>
112
113Creates a division of processes in a Cartesian grid. Argument
114{{NNODES}} is the number of nodes in the grid. Argument {{NDIMS}} is
115the number of Cartesian dimensions. The return values is an SRFI-4
116s32vector.
117
118
119
120<procedure>MPI:cart-coords :: COMM * RANK -> COORDS</procedure>
121
122Determines process coordinates in Cartesian topology, given a rank in
123the group. The return value is an SRFI-4 s32vector of length {{NDIMS}}
124(the number of dimensions in the Cartesian topology).
125
126
127
128=== Handling of communication groups
129
130
131<procedure>MPI:group? :: OBJ -> BOOL</procedure>
132
133Returns true if {{OBJ}} is an MPI group object, false otherwise.
134
135
136
137<procedure>MPI:comm-group :: COMM -> GROUP</procedure>
138Returns the group associated with the given communicator.
139
140
141<procedure>MPI:group-size :: GROUP -> INTEGER</procedure>
142Returns the size of the group {{GROUP}}.
143
144
145<procedure>MPI:group-rank :: GROUP -> INTEGER</procedure>
146Returns the rank of the calling process in the given group.
147
148
149<procedure>MPI:group-translate-ranks :: GROUP1 * RANKS * GROUP2 -> RANKS2</procedure>
150
151Translates the ranks of processes in one group to those in another
152group. The return value is an SRFI-4 s32vector.
153
154
155
156<procedure>MPI:group-union :: GROUP1 * GROUP2 -> GROUP</procedure>
157
158
159
160<procedure>MPI:group-difference :: GROUP1 * GROUP2 -> GROUP</procedure>
161
162
163
164<procedure>MPI:group-intersection :: GROUP1 * GROUP2 -> GROUP</procedure>
165
166
167
168<procedure>MPI:group-incl :: GROUP * RANKS -> GROUP</procedure>
169
170Produces a group by reordering an existing group and taking only
171members with the given ranks. Argument {{RANKS}} is an SRFI-4
172s32vector.
173
174
175
176<procedure>MPI:group-excl :: GROUP * RANKS -> GROUP</procedure>
177
178Produces a group by reordering an existing group and taking only
179members that do not have the given ranks. Argument {{RANKS}} is an
180SRFI-4 s32vector.
181
182=== MPI datatypes
183
184<procedure>MPI:datatype? :: OBJ -> BOOL</procedure>
185
186Returns true if `OBJ` is an MPI datatype object, false otherwise.
187
188<procedure>MPI:type-extent :: DATATYPE -> (EXTENT LB)</procedure>
189
190Returns the extent and lower bound of an MPI data type.
191
192<procedure>MPI:type-size :: DATATYPE -> INT</procedure>
193
194Returns the size of a datatype.
195
196
197* MPI:type-char
198* MPI:type-int
199* MPI:type-fixnum
200* MPI:type-flonum
201* MPI:type-byte
202* MPI:type-s8
203* MPI:type-u8
204* MPI:type-s16
205* MPI:type-u16
206* MPI:type-s32
207* MPI:type-u32
208* MPI:type-f32
209* MPI:type-f64
210
211Predefined MPI data types.
212
213<procedure>MPI:make-type-struct :: FIELD-COUNT * BLOCK-LENS * FIELDTYS -> DATATYPE</procedure>
214
215Given a gield count, field lengths and field types, creates and
216returns a new MPI structure data type with the given fields.
217
218
219=== Point-to-point communication
220
221
222Most communication procedures in this library come in several flavors,
223for fixnums, integers, floating point numbers, bytevectors, and for
224each of the SRFI-4 homogeneous vector types.
225
226<procedure>MPI:send :: DATATYPE * DATA * DEST * TAG * COMM -> UNDEFINED</procedure>
227<procedure>MPI:send-TYPE :: DATA * DEST * TAG * COMM -> UNDEFINED</procedure>
228
229Performs a standard-mode blocking send. Argument {{DEST}} is the rank
230of the destination process. Argument {{TAG}} is integer message
231tag. Argument {{DATATYPE}} is an MPI datatype object. {{TYPE}} is one
232of the following: {{fixnum, int, flonum, bytevector, s8vector,
233u8vector, s16vector, u16vector, s32vector, u32vector, f32vector,
234f64vector}}
235
236
237<procedure>MPI:receive :: DATATYPE * SOURCE * TAG * COMM -> DATA</procedure>
238<procedure>MPI:receive-TYPE :: LENGTH * SOURCE * TAG * COMM -> DATA</procedure>
239
240Performs a standard-mode blocking receive. Argument {{DEST}} is the
241rank of the destination process. Argument {{TAG}} is integer message
242tag. Argument {{LENGTH}} is present only in the vector
243procedures. {{TYPE}} is one of the following: {{fixnum, int, flonum,
244bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
245u32vector, f32vector, f64vector}}
246
247
248
249<procedure>MPI:probe :: DATATYPE * SOURCE * TAG * COMM -> (COUNT * SOURCE * TAG)</procedure>
250
251Checks for an incoming message. This is a blocking call that returns
252only after a matching message is found. Argument {{DATATYPE}} is an
253MPI datatype object. Argument {{SOURCE}} can be
254{{MPI:any-source}}. Argument {{TAG}} can be {{MPI:any-tag}}.
255
256
257=== Group communication
258
259
260<procedure>MPI:barrier :: COMM -> UNDEFINED</procedure>
261Barrier synchronization.
262
263
264<procedure>MPI:broadcast :: DATATYPE * DATA * ROOT * COMM -> UNDEFINED</procedure>
265<procedure>MPI:broadcast-TYPE :: DATA * ROOT * COMM -> UNDEFINED</procedure>
266
267Broadcasts a message from the process with rank root to all other
268processes of the group. Argument {{DATATYPE}} is an MPI datatype
269object. {{TYPE}} is one of the following: {{fixnum, int, flonum,
270bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
271u32vector, f32vector, f64vector}}
272
273
274
275<procedure>MPI:scatter :: DATATYPE * DATA * SENDCOUNT * ROOT * COMM -> DATA</procedure>
276<procedure>MPI:scatter-TYPE :: DATA * SENDCOUNT * ROOT * COMM -> DATA</procedure>
277
278Sends data from the root process to all processes in a group, and
279returns the data received by the calling process. Argument
280{{SENDCOUNT}} is the number of elements sent to each process. Argument
281{{DATATYPE}} is an MPI datatype object. Argument {{DATA}} is only
282required at the root process. All other processes can invoke this
283procedure with (void) as {{DATA}}. {{TYPE}} is one of the following:
284{{int, flonum, bytevector, s8vector, u8vector, s16vector, u16vector,
285s32vector, u32vector, f32vector, f64vector}}
286
287
288
289<procedure>MPI:scatterv :: DATATYPE * DATA * ROOT * COMM -> DATA</procedure>
290<procedure>MPI:scatterv-TYPE :: DATA * ROOT * COMM -> DATA</procedure>
291
292Sends variable-length data from the root process to all processes in a
293group, and returns the data received by the calling process.  Argument
294{{DATATYPE}} is an MPI datatype object. Argument {{DATA}} is only
295required at the root process, and is a list of values of type
296{{TYPE}}, where each element of the list is sent to the process of
297corresponding rank. All other processes can invoke this procedure with
298(void) as {{DATA}}. {{TYPE}} is one of the following: {{int, flonum,
299bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
300u32vector, f32vector, f64vector}}
301
302
303
304<procedure>MPI:gather :: DATATYPE * DATA * SENDCOUNT * ROOT * COMM -> DATA</procedure>
305<procedure>MPI:gather-TYPE :: DATA * SENDCOUNT * ROOT * COMM -> DATA</procedure>
306
307Gathers data from a group of processes, where each process send data
308of the same length.  Argument {{SENDCOUNT}} is the number of data
309elements being sent by each process. Argument {{DATATYPE}} is an MPI
310datatype object.  {{TYPE}} is one of the following: {{int, flonum,
311bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
312u32vector, f32vector, f64vector}}
313
314
315
316<procedure>MPI:gatherv :: DATATYPE * DATA * ROOT * COMM -> DATA</procedure>
317<procedure>MPI:gatherv-TYPE :: DATA * ROOT * COMM -> DATA</procedure>
318
319Gathers data from a group of processes, where each process can send
320data of variable length. Argument {{DATATYPE}} is an MPI datatype
321object. {{TYPE}} is one of the following: {{int, flonum, bytevector,
322s8vector, u8vector, s16vector, u16vector, s32vector, u32vector,
323f32vector, f64vector}}
324
325
326
327<procedure>MPI:allgather :: DATATYPE * DATA * ROOT * COMM -> DATA</procedure>
328<procedure>MPI:allgather-TYPE :: DATA * ROOT * COMM -> DATA</procedure>
329
330Gathers data of variable length from all processes and distributes it
331to all processes. Argument {{DATATYPE}} is an MPI datatype
332object. {{TYPE}} is one of the following: {{int, flonum, bytevector,
333s8vector, u8vector, s16vector, u16vector, s32vector, u32vector,
334f32vector, f64vector}}
335
336
337
338<procedure>MPI:reduce-TYPE :: DATA * OP * ROOT * COMM -> DATA</procedure>
339
340Reduces values on all processes within a group, using a global reduce
341operation, and return the result at the root process. {{OP}} is one of
342the following: {{MPI:i_max, MPI:i_min, MPI:i_sum, MPI:i_prod,
343MPI:i_land, MPI:i_lor, MPI:i_xor}} (integer operations); and
344{{MPI:f_max, MPI:f_min, MPI:f_sum, MPI:f_prod}} (floating point
345operations). {{TYPE}} is one of the following: {{int, flonum,
346bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
347u32vector, f32vector, f64vector}}
348
349
350
351<procedure>MPI:allreduce-TYPE :: DATA * OP * COMM -> DATA</procedure>
352
353Reduces values on all processes within a group, using a global reduce
354operation, and return the result at each process. {{OP}} is one of the
355following: {{MPI:i_max, MPI:i_min, MPI:i_sum, MPI:i_prod, MPI:i_land,
356MPI:i_lor, MPI:i_xor}} (integer operations); and {{MPI:f_max,
357MPI:f_min, MPI:f_sum, MPI:f_prod}} (floating point
358operations). {{TYPE}} is one of the following: {{int, flonum,
359bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
360u32vector, f32vector, f64vector}}
361
362
363
364<procedure>MPI:scan-TYPE :: DATA * OP * COMM -> DATA</procedure>
365
366Computes a partial reduction across the processes in a group. {{OP}}
367is one of the following: {{MPI:i_max, MPI:i_min, MPI:i_sum,
368MPI:i_prod, MPI:i_land, MPI:i_lor, MPI:i_xor}} (integer operations);
369and {{MPI:f_max, MPI:f_min, MPI:f_sum, MPI:f_prod}} (floating point
370operations). {{TYPE}} is one of the following: {{int, flonum,
371bytevector, s8vector, u8vector, s16vector, u16vector, s32vector,
372u32vector, f32vector, f64vector}}
373
374
375
376=== Round-robin routines
377
378
379The following variants of {{fold}}, {{map}} and {{for-each}} process
380lists in round-robin fashion on MPI nodes: for a given node {{n}},
381only list elements whose index is a modulo of n will be processed on
382this node.
383
384<procedure>MPI-rr-fold :: FN * INITIAL * XS -> RESULT</procedure>
385
386<procedure>MPI-rr-map :: FN * XS -> RESULT</procedure>
387
388<procedure>MPI-rr-for-each :: FN * XS -> VOID</procedure>
389
390
391
392== Examples
393
394
395=== Master/worker example
396
397<enscript highlight="scheme">
398;; Simple master/worker example
399;; Can be run as follows: mpirun -np 4 csi -s master-worker.scm
400;; where -np # indicates the number of processes
401
402(use srfi-4 mpi)
403
404(MPI:init)
405
406;; MPI uses objects called communicators to define how processes
407;; communicate with each other.  Almost all MPI routines require a
408;; communicator as an argument. 
409
410;; `MPI:get-comm-world' returns the communicator object which can send
411;; messages to all running MPI processes
412
413(define comm-world  (MPI:get-comm-world))
414
415;; `MPI:comm-size' returns the number of running MPI processes
416;;  (including the current one)
417
418(define size        (MPI:comm-size comm-world))
419
420;; `MPI:comm-rank' returns the rank of the calling MPI process
421
422(define myrank      (MPI:comm-rank comm-world))
423
424;; We assign rank 0 to be the master process, and the rest will be
425;; worker processes
426
427(if (zero? myrank)
428    (begin
429      (printf "[~a/~a]: I am the master\n" myrank size)
430      (let recur ((i 1))
431        (if (< i size)
432            (begin
433              ;; Send Hello message to process of rank i
434              (MPI:send-bytevector (string->blob (sprintf "Hello ~a..." i)) i 0 comm-world)
435              (recur (+ 1 i)))
436            ))
437
438      (let recur ((i 1))
439        (if (< i size)
440             ;; Wait for a response from process of rank i
441            (let ((n (blob->string (MPI:receive-bytevector i MPI:any-tag comm-world))))
442              (printf "[~a/~a]: received: ~a~%" myrank size n)
443              (recur (+ 1 i)))
444            ))
445      )
446    (begin
447      (printf "[~a/~a]: I am a worker\n" myrank size)
448      ;; Wait for a message from the master (process 0)
449      (let ((n (blob->string (MPI:receive-bytevector 0 MPI:any-tag comm-world))))
450        (printf "[~a/~a]: received: ~a\n" myrank size n)
451        ;; Send a response back to the master
452        (MPI:send-bytevector (string->blob (sprintf "Processor ~a reporting!" myrank))
453                     0 0 comm-world))
454      )
455    )
456
457(MPI:finalize)
458</enscript>
459
460=== Master/worker implemented with collective operations
461
462<enscript highlight="scheme">
463;; Master/worker example implemented with collective operations
464;; Can be run as follows: mpirun -np 4 csi -s master-worker.scm
465
466(use srfi-1 srfi-4 mpi)
467
468(MPI:init)
469
470;; MPI uses objects called communicators to define how processes
471;; communicate with each other.  Almost all MPI routines require a
472;; communicator as an argument. 
473
474;; `MPI:get-comm-world' returns the communicator object which can send
475;; messages to all running MPI processes
476
477(define comm-world  (MPI:get-comm-world))
478
479;; `MPI:comm-size' returns the number of running MPI processes
480;;  (including the current one)
481
482(define size        (MPI:comm-size comm-world))
483
484;; `MPI:comm-rank' returns the rank of the calling MPI process
485
486(define myrank      (MPI:comm-rank comm-world))
487
488;; We assign rank 0 to be the master process, and the rest will be
489;; worker processes
490
491(if (zero? myrank)
492    (begin
493      (printf "[~a/~a]: I am the master\n" myrank size)
494     
495      ;; data is a list of vectors to be sent to each process.  The
496      ;; master process sends element i from the list to process i
497      ;; (including itself). Note that each process must call scatterv
498      ;; in order to receive its data. In this example, the master
499      ;; ignores the result to its call to scatterv.
500
501      (let ((data (list-tabulate size (lambda (i) (string->blob (sprintf "Hello ~a..." i))))))
502        (MPI:scatterv-bytevector data 0 comm-world))
503   
504      ;; With gatherv, each process (master process included) sends
505      ;; the contents of its send buffer to the master process. The
506      ;; master process receives the messages and stores them in rank
507      ;; order.
508
509      (let ((v (MPI:gatherv-bytevector (string->blob "I am the master!") 0 comm-world)))
510        (printf "[~a/~a]: received: ~a\n" myrank size (map blob->string v))
511        ))
512    (begin
513      (printf "[~a/~a]: I am a worker\n" myrank size)
514
515      ;; The worker collects its data via a call to scatterv. The data
516      ;; argument is #f because the worker is not sending anything,
517      ;; just receiving.
518
519      (let ((n (blob->string (MPI:scatterv-bytevector #f 0 comm-world))))
520        (printf "[~a/~a]: received: ~a\n" myrank size n)
521
522        ;; The worker sends its result back to the master via a call to gatherv.
523        (MPI:gatherv-bytevector (string->blob (sprintf "Processor ~a reporting!" myrank))
524                                0 comm-world))
525      )
526    )
527
528(MPI:finalize)
529</enscript>
530
531
532== About this egg
533
534
535=== Author
536
537[[/users/ivan-raikov|Ivan Raikov]]
538
539=== Version history
540
541; 2.0 : Added support for MPI derived datatypes
542; 1.14 : Added simple round-robin routines
543; 1.12 : Fixes to allgather-int and allgather-flonum (thanks to Peter Bex)
544; 1.11 : Test script fixes
545; 1.9 : Ensure test script returns non-zero on error (thanks to mario)
546; 1.7 : Switched to wiki documentation
547; 1.6 : Ported to Chicken 4
548; 1.5 : Added a binding for MPI:spawn
549; 1.3 : Bug fix in MPI:scatter-int
550; 1.2 : Bug fix in the meta file
551; 1.1 : Bug fixes and improvements to the regression tests
552; 1.0 : Initial release
553
554=== License
555
556
557 Copyright 2007-2016 Ivan Raikov.
558 
559 Based on the Ocaml MPI library by Xavier Leroy.
560 
561 This program is free software: you can redistribute it and/or modify
562 it under the terms of the GNU General Public License as published by
563 the Free Software Foundation, either version 3 of the License, or (at
564 your option) any later version.
565 
566 This program is distributed in the hope that it will be useful, but
567 WITHOUT ANY WARRANTY; without even the implied warranty of
568 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
569 General Public License for more details.
570 
571 A full copy of the GPL license can be found at
572 <http://www.gnu.org/licenses/>.
573
Note: See TracBrowser for help on using the repository browser.