-
Notifications
You must be signed in to change notification settings - Fork 8
/
pingpong.lisp
72 lines (64 loc) · 2.8 KB
/
pingpong.lisp
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
67
68
69
70
71
72
;; A simple benchmark, where a message is sent back and forth between pairs
;; of processors
(in-package :cl-user)
(defpackage :cl-mpi/examples/pingpong
(:use :cl :alexandria :cl-mpi :static-vectors)
(:export #:main))
(in-package :cl-mpi/examples/pingpong)
(defun printf (fmt &rest args)
(format t "rank ~d: " (mpi-comm-rank))
(apply #'format t fmt args)
(finish-output))
(defun die (fmt &rest args)
(apply #'printf fmt args)
(mpi-finalize)
(uiop:quit))
(defun target-rank ()
(when (oddp (mpi-comm-size))
(die "pingpong requires an even number of processors~%")
(mpi-finalize)
(uiop:quit))
(let ((rank (mpi-comm-rank)))
(cond ((evenp rank) (1+ rank))
((oddp rank) (1- rank)))))
(defun pingpong (&rest message-sizes)
(with-static-vector (buffer (apply #'max message-sizes))
(loop for message-size in message-sizes
with target = (target-rank) do
(let ((iterations (ceiling 100000000 (+ message-size 1000)))
(tbegin (mpi-wtime)))
(loop repeat iterations do
(cond ((evenp target)
(mpi-send buffer target :end message-size)
(mpi-recv buffer target :end message-size))
((oddp target)
(mpi-recv buffer target :end message-size)
(mpi-send buffer target :end message-size)))
;; in case you want to compare the performance of cl-mpi
;; with low level CFFI calls, here is what the latter would
;; look like. (Spoiler: 100 nanoseconds, so dont bother)
;;
;; (cond ((evenp target)
;; (mpi::%mpi-send ptr count +mpi-byte+ target 0 comm)
;; (mpi::%mpi-recv ptr count +mpi-byte+ target 0 comm +mpi-status-ignore+))
;; ((oddp target)
;; (mpi::%mpi-recv ptr count +mpi-byte+ target 0 comm +mpi-status-ignore+)
;; (mpi::%mpi-send ptr count +mpi-byte+ target 0 comm)))
)
(let ((usec (* 1000000.0d0 (- (mpi-wtime) tbegin))))
(when (= (mpi-comm-rank) 0)
(printf "~9D bytes ~12,4F usec/msg ~8,2F MB/sec~%"
message-size
(/ usec iterations 2)
(/ (* message-size iterations 2) usec))))))))
(defun main (&optional args)
(mpi-init)
(let ((parsed-args (mapcar
(lambda (arg)
(or (parse-integer arg :junk-allowed t)
(die "pingpong [MSG-SIZE]*~%")))
args))
(default-args (loop for i below 30 collect (expt 2 i))))
(apply #'pingpong (or parsed-args default-args))
(mpi-finalize)
(uiop:quit)))