22
33import math
44import os
5+ import random
56import time
6- from typing import Any , Dict , Generator
7+ from dataclasses import dataclass
8+ from typing import Any , Dict , Generator , List , Tuple
79
810from netqasm .lang .parsing .text import parse_text_presubroutine
11+ from profiling import profile
912
1013from pydynaa import EventExpression
1114from squidasm .run .stack .config import (
2427 server_subrt_text = f .read ()
2528SERVER_SUBRT = parse_text_presubroutine (server_subrt_text )
2629
27- USE_CUSTOM_SUBROUTINES = False
30+ PRECOMPILE = False
31+ RANDOMIZE_ANGLE = False
2832
2933
3034class ClientProgram (Program ):
@@ -60,13 +64,23 @@ def run(
6064 p1 = epr .measure (store_array = False )
6165
6266 yield from conn .flush ()
67+
68+ start = time .time () * 1e6
69+ process_start = time .process_time () * 1e6
70+
6371 p1 = int (p1 )
6472
6573 delta1 = self ._alpha - self ._theta1 + (p1 + self ._r1 ) * math .pi
6674
75+ end = time .time () * 1e6
76+ process_end = time .process_time () * 1e6
77+
78+ duration = end - start
79+ process_duration = process_end - process_start
80+
6781 csocket .send_float (delta1 )
6882
69- return {"p1" : p1 }
83+ return {"p1" : p1 , "duration" : duration , "process_duration" : process_duration }
7084
7185
7286class ServerProgram (Program ):
@@ -93,33 +107,62 @@ def run(
93107 yield from conn .flush ()
94108
95109 delta1 = yield from csocket .recv_float ()
110+ if RANDOMIZE_ANGLE :
111+ delta1 = random .choice ([0 , PI_OVER_2 , PI , - PI_OVER_2 ])
96112 start = time .time () * 1e6
113+ process_start = time .process_time () * 1e6
97114
98- if USE_CUSTOM_SUBROUTINES :
115+ if PRECOMPILE :
99116 SERVER_SUBRT .app_id = conn .app_id
100117 # print(SERVER_SUBRT.commands[1].operands)
101118 SERVER_SUBRT .commands [1 ].operands [1 ] = 3
102119 SERVER_SUBRT .commands [1 ].operands [2 ] = 1
103- # for i in range(int(1e4)):
104- # pass
105120 end = time .time () * 1e6
121+ process_end = time .process_time () * 1e6
106122 yield from conn .commit_subroutine (SERVER_SUBRT )
107- m2 = 0
123+ m2 = conn . shared_memory . get_register ( "M0" )
108124 else :
109125 epr .rot_Z (angle = delta1 )
110126 epr .H ()
111127 m2 = epr .measure (store_array = False )
112128
113- # for i in range(int(1e4)):
114- # pass
115- end = time . time () * 1e6
129+ # end = time.time() * 1e6
130+ # process_end = time.process_time() * 1e6
131+ # yield from conn.flush()
116132
117- yield from conn .flush ()
133+ subroutine = conn ._builder ._pop_pending_subroutine ()
134+ end = time .time () * 1e6
135+ process_end = time .process_time () * 1e6
136+ yield from conn .commit_subroutine (subroutine )
118137 m2 = int (m2 )
119138
120139 duration = end - start
140+ process_duration = process_end - process_start
141+
142+ return {"m2" : m2 , "duration" : duration , "process_duration" : process_duration }
143+
144+
145+ @dataclass
146+ class Statistics :
147+ name : str
148+ mean : float
149+ std_error : float
150+ min_value : float
151+ max_value : float
121152
122- return {"m2" : m2 , "duration" : duration }
153+ def to_string (self ):
154+ return f"[{ self .name } ] { self .mean } , { self .std_error } (max: { self .max_value } , min: { self .min_value } )"
155+
156+
157+ def compute_statistics (name : str , items : List [Any ]) -> Statistics :
158+ length = len (items )
159+ mean = round (sum (items ) / length , 3 )
160+ variance = sum ((d - mean ) * (d - mean ) for d in items ) / length
161+ std_deviation = math .sqrt (variance )
162+ std_error = round (std_deviation / math .sqrt (length ), 3 )
163+ min_value = min (items )
164+ max_value = max (items )
165+ return Statistics (name , mean , std_error , min_value , max_value )
123166
124167
125168def get_distribution (
@@ -132,30 +175,40 @@ def get_distribution(
132175 client_program = ClientProgram (alpha = alpha , theta1 = theta1 , r1 = r1 )
133176 server_program = ServerProgram ()
134177
135- _ , server_results = run (
178+ client_results , server_results = run (
136179 cfg , {"client" : client_program , "server" : server_program }, num_times
137180 )
138181
139182 durations = [result ["duration" ] for result in server_results ]
183+ process_durations = [result ["process_duration" ] for result in server_results ]
140184 # print(durations)
141-
142- mean = round (sum (durations ) / len (durations ), 3 )
143- variance = sum ((d - mean ) * (d - mean ) for d in durations ) / len (durations )
144- std_deviation = math .sqrt (variance )
145- std_error = round (std_deviation / math .sqrt (len (durations )), 3 )
146-
147- max_dur = max (durations )
148- min_dur = min (durations )
149-
150- print (f"{ mean } , { std_error } (max: { max_dur } , min: { min_dur } )" )
185+ m2s = [result ["m2" ] for result in server_results ]
186+
187+ client_durations = [result ["duration" ] for result in client_results ]
188+ client_process_durations = [result ["process_duration" ] for result in client_results ]
189+
190+ print ("\n server:" )
191+ print (compute_statistics ("durations" , durations ).to_string ())
192+ print (compute_statistics ("process_durations" , process_durations ).to_string ())
193+ # print(compute_statistics("m2", m2s).to_string())
194+
195+ print ("\n client:" )
196+ print (compute_statistics ("client_durations" , client_durations ).to_string ())
197+ print (
198+ compute_statistics (
199+ "client_process_durations" , client_process_durations
200+ ).to_string ()
201+ )
202+ print (client_durations )
151203
152204
153205PI = math .pi
154206PI_OVER_2 = math .pi / 2
155207
156208
209+ # @profile(sort_by="cumulative", lines_to_print=1000, strip_dirs=True)
157210def main ():
158- num_times = 100
211+ num_times = 1000
159212
160213 client_stack = StackConfig (
161214 name = "client" ,
@@ -179,7 +232,12 @@ def main():
179232
180233
181234if __name__ == "__main__" :
182- USE_CUSTOM_SUBROUTINES = False
235+ RANDOMIZE_ANGLE = True
236+
237+ print ("NO PRECOMPILE:" )
238+ PRECOMPILE = False
183239 main ()
184- USE_CUSTOM_SUBROUTINES = True
240+
241+ print ("\n PRECOMPILE:" )
242+ PRECOMPILE = True
185243 main ()
0 commit comments