Skip to content

Commit 15ac5e2

Browse files
author
David, Mark H
committed
add cl-quil-benchmarking system quilc-perf for perf. benchmarking
This is part of issue "Investigate performance at 72-150 qubits #565". new modules: benchmarking/quilc-perf.lisp - primarily exports benchmark-nq function to get timings as nQ increases for various chip and program types benchmarking/quilc-mon-prof.lisp - builds on quilc-perf.lisp and is for monitoring and profiling, as opposed to simple benchmarks, and is a WIP. Makefile - add targets to run benchmark-nq a couple of ways cl-quil-benchmarking.asd - add new module quilc-perf and depend on 3 additional systems: metering, qvm-app, sb-sprof
1 parent 86b0171 commit 15ac5e2

File tree

5 files changed

+530
-24
lines changed

5 files changed

+530
-24
lines changed

Makefile

+12-1
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,24 @@ test-ccl:
164164
###############################################################################
165165
# BENCHMARKS
166166
###############################################################################
167-
.PHONY: benchmark-qasm
167+
.PHONY: benchmark-qasm benchmark-qasm-big
168168

169169
benchmark-qasm:
170170
$(QUICKLISP) \
171171
--eval "(ql:quickload :cl-quil-benchmarking)" \
172172
--eval "(cl-quil-benchmarking::benchmark-qasm-suite)"
173173

174+
benchmark-nq:
175+
$(QUICKLISP) \
176+
--eval "(ql:quickload :cl-quil-benchmarking)" \
177+
--eval "(cl-quil-benchmarking::benchmark-nq)"
178+
179+
benchmark-nq-2x:
180+
$(QUICKLISP) \
181+
--eval "(ql:quickload :cl-quil-benchmarking)" \
182+
--eval "(cl-quil-benchmarking::benchmark-nq)" \
183+
--eval "(cl-quil-benchmarking::benchmark-nq)"
184+
174185
###############################################################################
175186
# CLEAN
176187
###############################################################################

benchmarking/qasm-benchmarks.lisp

+29-23
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
:do (quil::append-instruction-to-lschedule lschedule instr)
6161
:finally (return (quil::lscheduler-calculate-depth lschedule)))))
6262

63-
(defun benchmark-qasm-suite (&key (timeout 30))
63+
(defun benchmark-qasm-suite (&key (timeout 30) named)
64+
"Run benchmarks from qasm suite. If NAMED is not nil, the specified test(s) will be the ONLY one(s) run; otherwise, all the tests are run. NAMED should be a short name (as shown in the output) of a test, either as a symbol or string, or a list thereof (i.e., matching mutiple tests), to be compared using string-equal. TIMEOUT specifies a timeout in seconds, defaulting to 30 seconds."
6465
(let ((timed-out nil))
6566
(flet ((print-rule ()
6667
(format t "+------------------+----------+-------+----------+~%")))
@@ -73,28 +74,33 @@
7374
(quil::*addresser-use-1q-queues* t)
7475
(quil::*safe-include-directory* (asdf:system-relative-pathname :cl-quil "tests/qasm-files/")))
7576
(dolist (file (qasm-test-files))
76-
(format t "| ~Va " 16 (trim-long-string (pathname-name file) 16))
77-
(finish-output)
78-
(handler-case
79-
(let ((text (alexandria:read-file-into-string file)))
80-
(tg:gc :full t)
81-
(bordeaux-threads:with-timeout (timeout)
82-
(with-stopwatch elapsed-time
83-
(multiple-value-bind (cpp swaps)
84-
(quil::compiler-hook (quil::parse text
85-
:originating-file file)
86-
chip
87-
:protoquil t
88-
:destructive t)
89-
(format t "| ~Vf | ~Vd | ~Vd |~%"
90-
8 (/ elapsed-time 1000)
91-
5 swaps
92-
8 (calculate-multiqubit-gate-depth (parsed-program-executable-code cpp)))))))
93-
(bt:timeout ()
94-
(format t "| ~8,'>d | ????? | ???????? |~%"
95-
timeout)
96-
(push (pathname-name file) timed-out)))
97-
(finish-output)))
77+
(let ((short-name (trim-long-string (pathname-name file) 16)))
78+
(when (or (null named)
79+
(if (atom named)
80+
(string-equal named short-name)
81+
(member short-name named :test 'string-equal)))
82+
(format t "| ~Va " 16 short-name)
83+
(finish-output)
84+
(handler-case
85+
(let ((text (alexandria:read-file-into-string file)))
86+
(tg:gc :full t)
87+
(bordeaux-threads:with-timeout (timeout)
88+
(with-stopwatch elapsed-time
89+
(multiple-value-bind (cpp swaps)
90+
(quil::compiler-hook (quil::parse text
91+
:originating-file file)
92+
chip
93+
:protoquil t
94+
:destructive t)
95+
(format t "| ~Vf | ~Vd | ~Vd |~%"
96+
8 (/ elapsed-time 1000)
97+
5 swaps
98+
8 (calculate-multiqubit-gate-depth (parsed-program-executable-code cpp)))))))
99+
(bt:timeout ()
100+
(format t "| ~8,'>d | ????? | ???????? |~%"
101+
timeout)
102+
(push (pathname-name file) timed-out)))
103+
(finish-output)))))
98104
(print-rule)
99105
(terpri)
100106
(when timed-out

benchmarking/quilc-mon-prof.lisp

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
;;;; quilc-mon-prof.lisp
2+
;;;;
3+
;;;; Author: Mark David
4+
5+
(in-package #:cl-quil-benchmarking)
6+
7+
8+
9+
;;;; Monitoring and Profiling
10+
11+
;; This builds on quilc-perf.lisp and is for monitoring and profiling,
12+
;; as opposed to simple benchmarks, and is a WIP.
13+
14+
15+
(defparameter *monitor-types*
16+
'(:mon #+sbcl :sb-sprof))
17+
18+
(defun monitor-run (program-type chip-type nq repeats monitor
19+
&optional report-type sample-interval)
20+
(when (not (member monitor *monitor-types*))
21+
(unless (null monitor) ; if so, just silently default with no warning
22+
(warn "unrecognized monitor, should be one of ~s; using ~s"
23+
*monitor-types* (first *monitor-types*)))
24+
(setq monitor (first *monitor-types*)))
25+
(let (program chip)
26+
(format t "~2%****~%Building ~a program (nQ = ~d)... " program-type nq)
27+
(setq program (get-or-build-benchmark-program nq program-type))
28+
(format t "DONE (~a).~%" program)
29+
(format t "Building ~a chip (nQ = ~d)... " chip-type nq)
30+
(setq chip (get-or-build-benchmark-chip nq chip-type))
31+
(format t "DONE (~a).~%" chip)
32+
(format t "** Doing ~d run~p... **~%" repeats repeats)
33+
(let* ((*package* (find-package :cl-quil))
34+
(thunk
35+
#'(lambda ()
36+
(dotimes (i repeats)
37+
(prepare-environment-for-perf-run)
38+
(format t "#~d: Compiling program/chip ... " i)
39+
(let* ((t1 (get-internal-run-time))
40+
(t2 (progn (do-one-quilc-perf-run program chip)
41+
(get-internal-run-time)))
42+
(elapsed-time (- t2 t1)))
43+
(format
44+
t
45+
"DONE (~,2f sec compiler, ~2df sec real time w/overhead).~%"
46+
;; -- 2nd timing is real time, as opposed to
47+
;; internal run time. 'Overhead' is primarily GC +
48+
;; warming.
49+
(internal-time-to-seconds elapsed-time)
50+
(internal-time-to-seconds (- t2 t1))))))))
51+
(ecase monitor
52+
(:mon (mon:monitor-form (funcall thunk)))
53+
#+sbcl
54+
(:sb-sprof
55+
(progn
56+
(sb-sprof:reset)
57+
(sb-sprof:start-profiling
58+
;; :sample-interval (or sample-interval 0.005) ; default = 0.01
59+
:sample-interval 0.0001
60+
:threads (list sb-thread:*current-thread*))
61+
(funcall thunk)
62+
(sb-sprof:report
63+
:min-percent 3
64+
:type (ecase report-type
65+
((nil :flat) :flat)
66+
(:graph :graph)))))))
67+
(format t "** DONE with ~d runs. **~%" repeats)))
68+
69+
(defun do-monitor-runs (&key start step end
70+
repeats monitor
71+
report-type sam sample-interval)
72+
(or repeats (setq repeats 3))
73+
(loop :for nq := (or start 10)
74+
:then (+ nq (or step 10))
75+
:when (> nq (or end start))
76+
:do (return)
77+
:do (format t "~%**** NQ: ~d ****~%" nq)
78+
(loop :for program-type :in *benchmark-program-types*
79+
:do (loop :for chip-type :in *benchmark-chip-connectedness-types*
80+
:do (monitor-run
81+
program-type chip-type nq repeats monitor
82+
report-type sample-interval)))))
83+
84+
;; Try this on SBCL: (do-monitor-runs :monitor ':sb-sprof)
85+
86+
87+
88+
89+
(defun do-one (nq)
90+
(do-one-nq-program-chip nq :hadamard :fully-connected))
91+
92+
(defparameter *min-sb-sprof-perf-pct* 1)
93+
94+
(defun do-one-nq-program-chip (nq program-type chip-type)
95+
(let ((program (build-benchmark-program nq :hadamard))
96+
(chip (build-benchmark-chip nq :fully-connected)))
97+
(sb-sprof:reset)
98+
(tg:gc :full t)
99+
(sb-sprof:start-profiling :threads (list sb-thread:*current-thread*))
100+
(time (benchmark-one-quilc-perf-run program chip))
101+
(sb-sprof:stop-profiling)
102+
(sb-sprof:report :type :graph :min-percent *min-sb-sprof-perf-pct*)
103+
(sb-sprof:report :type :flat :min-percent *min-sb-sprof-perf-pct*)))
104+
105+
(defun do-one-mon (nq &optional program-type)
106+
(let ((program (build-benchmark-program nq (or program-type :hadamard)))
107+
(chip (build-benchmark-chip nq :fully-connected)))
108+
(tg:gc :full t)
109+
(sb-sprof:with-profiling (:max-samples 1000
110+
:report :flat
111+
:loop nil
112+
113+
:reset t
114+
:sample-interval 0.01) ; default .01
115+
(benchmark-one-quilc-perf-run program chip))))
116+
117+
118+
119+
120+
;;;; depth check
121+
122+
(defun quil-parse-to-logical-schedule (parse)
123+
(let* ((instructions-vector (quil:parsed-program-executable-code parse))
124+
(instructions-list (concatenate 'list instructions-vector))
125+
(lsched (quil.si:make-lscheduler)))
126+
(quil.si:append-instructions-to-lschedule lsched instructions-list)
127+
lsched))
128+
129+
(defun depth-check (nq)
130+
(let* ((parse (build-benchmark-program nq :hadamard))
131+
(logical-schedule (quil-parse-to-logical-schedule parse)))
132+
(depth-check-1 logical-schedule)))
133+
134+
(defun depth-check-1 (logical-schedule)
135+
(let* ((old-walk-depth
136+
(let ((quil::*new-walk* nil))
137+
(quil::lscheduler-calculate-depth logical-schedule)))
138+
(new-walk-depth
139+
(let ((quil::*new-walk* t))
140+
(quil::lscheduler-calculate-depth logical-schedule))))
141+
(list
142+
(= old-walk-depth new-walk-depth)
143+
old-walk-depth new-walk-depth logical-schedule)))
144+
145+
146+
147+
;;;; SB-SPROF run 20, 50, 80, 110, 140
148+
149+
(defun sb-sprof-run ()
150+
(loop for nq in '(20 50 80 110)
151+
do (do-monitor-runs
152+
:start nq
153+
:monitor :sb-sprof
154+
:repeats 1
155+
:report-type :flat)))
156+
157+
(defun sb-sprof-graph ()
158+
(loop for nq in '(20 50 80 110)
159+
do (do-monitor-runs
160+
:start nq
161+
:monitor :sb-sprof
162+
:repeats 1
163+
:report-type :flat)))
164+
165+
(defun sb-sprof-run-high-sample ()
166+
(loop for nq in '(20 50 80 110)
167+
do (do-monitor-runs
168+
:start nq
169+
:monitor :sb-sprof
170+
:repeats 1
171+
172+
:sample-interval 0.001 ; our default: 0.005
173+
:report-type :flat)))
174+
175+
(defun sb-sprof-run-high-sample-plus-graph ()
176+
(loop for nq in '(20 50 80 110)
177+
do (do-monitor-runs
178+
:start nq
179+
:monitor :sb-sprof
180+
:repeats 1
181+
182+
:sample-interval 0.001 ; our default: 0.005
183+
:report-type :graph))) ; our default: :flat
184+
185+
(defun sb-sprof-run-mon ()
186+
(loop for nq in '(20 50 80 110)
187+
do (do-monitor-runs
188+
:start nq
189+
:monitor :mon
190+
:repeats 1
191+
192+
:sample-interval 0.001 ; our default: 0.005
193+
:report-type :graph))) ; our default: :flat
194+
195+
(defun one-monitor-run-bill-linear (nq)
196+
(monitor-run :bell :linear nq 1 :mon :flat .0001))
197+

0 commit comments

Comments
 (0)