@@ -96,21 +96,20 @@ class CompileOptions:
96
96
Most correspond directly to qss-compiler CLI arguments.
97
97
"""
98
98
99
- input_type : InputType = InputType .QASM3
100
99
"""Input source type."""
101
- output_type : OutputType = OutputType . QEM
100
+ input_type : InputType = InputType . QASM3
102
101
"""Output source type."""
103
- output_file : Union [ str , None ] = None
102
+ output_type : OutputType = OutputType . QEM
104
103
"""Output file, if not supplied raw bytes will be returned."""
105
- target : Optional [str ] = None
104
+ output_file : Union [str , None ] = None
106
105
"""Hardware target to select."""
107
- config_path : Union [str , None ] = None
106
+ target : Optional [str ] = None
108
107
"""Hardware configuration location."""
109
- num_shots : Optional [ int ] = None
108
+ config_path : Union [ str , None ] = None
110
109
"""Number of shots to run each circuit for."""
111
- shot_delay : Optional [float ] = None
110
+ num_shots : Optional [int ] = None
112
111
"""Repetition delay between shots in seconds."""
113
- extra_args : List [ str ] = field ( default_factory = list )
112
+ shot_delay : Optional [ float ] = None
114
113
"""Optional list of extra arguments to pass to the compiler.
115
114
116
115
Individual arguments must be separate arguments in the list.
@@ -121,8 +120,9 @@ class CompileOptions:
121
120
resulting in args being set twice, eg., `num_shots` and `--num-shots`.
122
121
This will result in an error.
123
122
"""
124
- on_diagnostic : Optional [ Callable [[ Diagnostic ], Any ]] = None
123
+ extra_args : List [ str ] = field ( default_factory = list )
125
124
"""Optional callback for processing diagnostic messages from the compiler."""
125
+ on_diagnostic : Optional [Callable [[Diagnostic ], Any ]] = None
126
126
127
127
def prepare_compiler_option_args (self ) -> List [str ]:
128
128
"""Prepare the compiler option arguments from this dataclass."""
@@ -168,7 +168,9 @@ def prepare_compiler_args(self) -> List[str]:
168
168
args .append ("--direct" )
169
169
args .append (str (self .input_str ))
170
170
else :
171
- raise exceptions .QSSCompilerNoInputError ("Neither input file nor input string provided." )
171
+ raise exceptions .QSSCompilerNoInputError (
172
+ "Neither input file nor input string provided."
173
+ )
172
174
173
175
return args
174
176
@@ -219,7 +221,9 @@ def on_diagnostic(diag):
219
221
conn .send_bytes (output )
220
222
221
223
222
- def _do_compile (execution : _CompilerExecution ) -> Union [bytes , str , None ]:
224
+ def _do_compile (
225
+ execution : _CompilerExecution , return_diagnostics : bool = False
226
+ ) -> Union [bytes , str , None ]:
223
227
assert (
224
228
execution .input_file is not None or execution .input_str is not None
225
229
), "one of the compile options input_file or input_str must be set"
@@ -249,8 +253,8 @@ def _do_compile(execution: _CompilerExecution) -> Union[bytes, str, None]:
249
253
received = parent_side .recv ()
250
254
251
255
if isinstance (received , Diagnostic ):
252
- if execution . options .on_diagnostic :
253
- execution . options .on_diagnostic (received )
256
+ if options .on_diagnostic :
257
+ options .on_diagnostic (received )
254
258
else :
255
259
diagnostics .append (received )
256
260
elif isinstance (received , _CompilerStatus ):
@@ -262,7 +266,8 @@ def _do_compile(execution: _CompilerExecution) -> Union[bytes, str, None]:
262
266
raise exceptions .QSSCompilerCommunicationFailure (
263
267
"The compile process delivered an unexpected object instead of status or "
264
268
"diagnostic information. This points to inconsistencies in the Python "
265
- "interface code between the calling process and the compile process."
269
+ "interface code between the calling process and the compile process." ,
270
+ return_diagnostics = return_diagnostics ,
266
271
)
267
272
268
273
if options .output_file is None :
@@ -275,7 +280,9 @@ def _do_compile(execution: _CompilerExecution) -> Union[bytes, str, None]:
275
280
childproc .kill ()
276
281
childproc .join ()
277
282
raise exceptions .QSSCompilerEOFFailure (
278
- "Compile process exited before delivering output." , diagnostics
283
+ "Compile process exited before delivering output." ,
284
+ diagnostics ,
285
+ return_diagnostics = return_diagnostics ,
279
286
)
280
287
281
288
childproc .join ()
@@ -287,17 +294,23 @@ def _do_compile(execution: _CompilerExecution) -> Union[bytes, str, None]:
287
294
+ (" yet appears still alive" if childproc .is_alive () else "" )
288
295
),
289
296
diagnostics ,
297
+ return_diagnostics = return_diagnostics ,
290
298
)
291
299
292
300
if not success :
293
- raise exceptions .QSSCompilationFailure ("Failure during compilation" , diagnostics )
301
+ raise exceptions .QSSCompilationFailure (
302
+ "Failure during compilation" ,
303
+ diagnostics ,
304
+ return_diagnostics = return_diagnostics ,
305
+ )
294
306
295
307
except mp .ProcessError as e :
296
308
raise exceptions .QSSCompilerError (
297
309
"It's likely that you've hit a bug in the QSS Compiler. Please "
298
310
"submit an issue to the team with relevant information "
299
311
"(https://github.com/Qiskit/qss-compiler/issues):\n "
300
- f"{ e } "
312
+ f"{ e } " ,
313
+ return_diagnostics = return_diagnostics ,
301
314
)
302
315
303
316
if options .output_file is None :
@@ -321,6 +334,7 @@ def _stringify_path(p):
321
334
322
335
def compile_file (
323
336
input_file : Union [Path , str ],
337
+ return_diagnostics : bool = False ,
324
338
compile_options : Optional [CompileOptions ] = None ,
325
339
** kwargs ,
326
340
) -> Union [bytes , str , None ]:
@@ -332,6 +346,7 @@ def compile_file(
332
346
333
347
Args:
334
348
input_file: Path to the input file to compile.
349
+ return_diagnostics: diagnostics visibility flag
335
350
compile_options: Optional :class:`CompileOptions` dataclass.
336
351
kwargs: Keywords corresponding to :class:`CompileOptions`. Ignored if `compile_options`
337
352
is provided directly.
@@ -343,11 +358,12 @@ def compile_file(
343
358
input_file = _stringify_path (input_file )
344
359
compile_options = _prepare_compile_options (compile_options , ** kwargs )
345
360
execution = _CompilerExecution (input_file = input_file , options = compile_options )
346
- return _do_compile (execution )
361
+ return _do_compile (execution , return_diagnostics )
347
362
348
363
349
364
async def compile_file_async (
350
365
input_file : Union [Path , str ],
366
+ return_diagnostics : bool = False ,
351
367
compile_options : Optional [CompileOptions ] = None ,
352
368
** kwargs ,
353
369
) -> Union [bytes , str , None ]:
@@ -358,6 +374,7 @@ async def compile_file_async(
358
374
359
375
Args:
360
376
input_file: Path to the input file to compile.
377
+ return_diagnostics: diagnostics visibility flag
361
378
compile_options: Optional :class:`CompileOptions` dataclass.
362
379
kwargs: Keywords corresponding to :class:`CompileOptions`. Ignored if `compile_options`
363
380
is provided directly.
@@ -371,14 +388,17 @@ async def compile_file_async(
371
388
execution = _CompilerExecution (input_file = input_file , options = compile_options )
372
389
with ThreadPoolExecutor () as executor :
373
390
loop = asyncio .get_running_loop ()
374
- return await loop .run_in_executor (executor , _do_compile , execution )
391
+ return await loop .run_in_executor (
392
+ executor , _do_compile , execution , return_diagnostics
393
+ )
375
394
# As an alternative, ProcessPoolExecutor has somewhat higher overhead yet
376
395
# reduces complexity of integration by not requiring the preparatory call
377
396
# to set_start_method.
378
397
379
398
380
399
def compile_str (
381
400
input_str : str ,
401
+ return_diagnostics : bool = False ,
382
402
compile_options : Optional [CompileOptions ] = None ,
383
403
** kwargs ,
384
404
) -> Union [bytes , str , None ]:
@@ -391,6 +411,7 @@ def compile_str(
391
411
392
412
Args:
393
413
input_str: input to compile as string (e.q., an OpenQASM3 program).
414
+ return_diagnostics: diagnostics visibility flag
394
415
compile_options: Optional :class:`CompileOptions` dataclass.
395
416
kwargs: Keywords corresponding to :class:`CompileOptions`. Ignored if `compile_options`
396
417
is provided directly.
@@ -401,11 +422,12 @@ def compile_str(
401
422
"""
402
423
compile_options = _prepare_compile_options (compile_options , ** kwargs )
403
424
execution = _CompilerExecution (input_str = input_str , options = compile_options )
404
- return _do_compile (execution )
425
+ return _do_compile (execution , return_diagnostics = return_diagnostics )
405
426
406
427
407
428
async def compile_str_async (
408
429
input_str : str ,
430
+ return_diagnostics : bool = False ,
409
431
compile_options : Optional [CompileOptions ] = None ,
410
432
** kwargs ,
411
433
) -> Union [bytes , str , None ]:
@@ -416,6 +438,7 @@ async def compile_str_async(
416
438
417
439
Args:
418
440
input_str: input to compile as string (e.q., an OpenQASM3 program).
441
+ return_diagnostics: diagnostics visibility flag
419
442
compile_options: Optional :class:`CompileOptions` dataclass.
420
443
kwargs: Keywords corresponding to :class:`CompileOptions`. Ignored if `compile_options`
421
444
is provided directly.
@@ -429,7 +452,9 @@ async def compile_str_async(
429
452
execution = _CompilerExecution (input_str = input_str , options = compile_options )
430
453
with ThreadPoolExecutor () as executor :
431
454
loop = asyncio .get_running_loop ()
432
- return await loop .run_in_executor (executor , _do_compile , execution )
455
+ return await loop .run_in_executor (
456
+ executor , _do_compile , execution , return_diagnostics
457
+ )
433
458
# As an alternative, ProcessPoolExecutor has somewhat higher overhead yet
434
459
# reduces complexity of integration by not requiring the preparatory call
435
460
# to set_start_method.
0 commit comments