2626import time
2727import copy
2828import json
29+ import math
2930
3031from _common import qcb_mpi as mpi
3132from _common import metrics
@@ -229,6 +230,8 @@ def execute_circuit (batched_circuit):
229230 # Initiate execution
230231 circuit = batched_circuit["qc"]
231232
233+ ############
234+
232235 # create a pseudo-job to perform metrics processing upon return
233236 job = Job()
234237
@@ -273,18 +276,15 @@ def execute_circuit (batched_circuit):
273276
274277 # ***********************************
275278
276- # store circuit dimensional metrics
277- # DEVNOTE: this is not accurate; it is provided so the volumetric plots show something
278-
279- # compute depth and gate counts based on number of qubits
279+ # number of qubits is stored in the "group" field
280280 qc_size = int(active_circuit["group"])
281- qc_depth = 4 * pow(qc_size, 2)
282-
283- qc_xi = 0.5
284-
285- qc_n2q = int(qc_depth * 0.75)
281+
282+ # obtain initial circuit metrics
283+ qc_depth, qc_size, qc_count_ops, qc_xi, qc_n2q = get_circuit_metrics(circuit, qc_size)
284+
286285 qc_tr_depth = qc_depth
287286 qc_tr_size = qc_size
287+ qc_tr_count_ops = qc_count_ops
288288 qc_tr_xi = qc_xi
289289 qc_tr_n2q = qc_n2q
290290
@@ -302,6 +302,57 @@ def execute_circuit (batched_circuit):
302302 ##############
303303 # Here we complete the job immediately
304304 job_complete(job)
305+
306+
307+ # Get circuit metrics fom the circuit passed in
308+ def get_circuit_metrics(qc, qc_size):
309+
310+ # get resource info from cudaq
311+ resources = cudaq.estimate_resources(qc[0], *qc[1])
312+ resources_str = str(resources)
313+
314+ import re
315+
316+ # Get total gates (not needed as we use the .count() function)
317+ #total_match = re.search(r'Total # of gates:\s*(\d+)', resources_str)
318+ #total_gates = int(total_match.group(1)) if total_match else 0
319+
320+ total_gates = resources.count()
321+
322+ # the resources object returned is not a dict; need to parse the string to get 2q gates
323+ # Get all gate counts that start with 'c' (controlled/2-qubit gates)
324+ two_qubit_gates = 0
325+ for line in resources_str.split('\n'):
326+ match = re.match(r'\s*(c\w+)\s*:\s*(\d+)', line)
327+ if match:
328+ two_qubit_gates += int(match.group(2))
329+
330+ # print(f"Total: {total_gates}, 2-qubit: {two_qubit_gates}")
331+
332+ qc_depth = estimate_depth(qc_size, total_gates, two_qubit_gates)
333+ #print(qc_depth)
334+
335+ qc_xi = two_qubit_gates / max(total_gates, 1)
336+ qc_n2q = two_qubit_gates
337+
338+ qc_count_ops = total_gates
339+
340+ return qc_depth, qc_size, qc_count_ops, qc_xi, qc_n2q
341+
342+ # Make estimate of circuit depth using heuristic approach
343+ def estimate_depth(num_qubits, total_gates, two_qubit_gates):
344+ N = num_qubits
345+ K = two_qubit_gates
346+ S = total_gates - K
347+
348+ # Theoretical minimum (perfect packing - 2Qs and 1Qs and MZ)
349+ depth_min = math.ceil(2*K / N) + math.ceil(S / N) + 1
350+
351+ # Realistic estimate (assume 40% packing efficiency)
352+ depth_estimate = depth_min * 2.5
353+
354+ return depth_estimate
355+
305356
306357# klunky way to know the last group executed
307358last_group = None
0 commit comments