def thaw_promise(self, job_id, device: QuTechDevice): """ load job by job_id """ try: return device.device.retrieve_job(job_id) except ApiError as e: print_stderr(str(e)) return None
def thaw_promise(self, job_id, device: IBMDevice): """ load job by job_id """ try: return device.device.retrieve_job(job_id) except QiskitError as e: print_stderr(e) return None
def job_alive(self, promise, meta: dict): """ check whether we consider the job behind the promise alive on an QuTech backend; however we should also check whether job_id is successful since only that makes a call to the cloud backend """ try: id = promise.job_id() except ApiError as e: message = str(e) if "Please wait for those jobs to finish or cancel a job." in str( e): print_stderr(str(e)) return False raise # note that if this fails due to e.g. a TimeoutError # this does not mean that the job is broken; # it could e.g. be a network issue. We let that error propagate status = promise.status() print( f"The job with QuTech ID {id} is reported to be in status: {status}" ) if status in [JobStatus.QUEUED, JobStatus.RUNNING, JobStatus.DONE]: return True elif status in [JobStatus.ERROR, JobStatus.CANCELLED, "FAILURE"]: return False # check whether status has been like this before if not "last-status" in meta or meta["last-status"]["status"] != status: meta["last-status"] = {"status": status, "time": utc_timestamp()} return True # calculate time difference; if below threshold all is ok age = time_elapsed(meta["last-status"]["time"]) if age <= self.MAX_JOB_AGE: return True # otherwise try to cancel old job print( f"The job with QuTech ID {id} seems stuck in status: {status} for more than {age}, trying to cancel it." ) try: promise.cancel() del meta["last-status"] except ApiError as e: print_stderr(str(e)) finally: return False
def execute( self, circuit: qiskit.QuantumCircuit, num_shots=1024, initial_layout=None, optimization_level=3, ): while optimization_level >= 0: try: experiment = qiskit.compiler.transpile( circuit, initial_layout=initial_layout, optimization_level=optimization_level, backend=self.device, ) break except qiskit.transpiler.exceptions.TranspilerError as e: print_stderr("transpiler error. Lowering optimization level") optimization_level -= 1 if optimization_level < 0: raise e print_hl(circuit, color="white") print_hl(experiment, color="white") qobj = qiskit.compiler.assemble(experiment, shots=num_shots, max_credits=15, backend=self.device) try: return { "result": self.device.run(qobj), "transpiled_circuit": experiment } except QiskitError as e: message = e.message.rstrip("\n .") message = e.message.rstrip(".'") if message.endswith("Error code: 3458"): print_stderr("You don't have enough credits to run this job.") return { "result": ThinPromise(lambda: None), "transpiled_circuit": None } raise
def execute( self, circuit: qiskit.QuantumCircuit, num_shots=1024, initial_layout=None, optimization_level=3, ): while optimization_level >= 0: try: experiment = qiskit.compiler.transpile( circuit, initial_layout=initial_layout, optimization_level=optimization_level, backend=self.device, ) break except qiskit.transpiler.exceptions.TranspilerError as e: print_stderr("transpiler error. Lowering optimization level") optimization_level -= 1 if optimization_level < 0: raise e print_hl(circuit, color="white") print_hl(experiment, color="white") qobj = qiskit.compiler.assemble(experiment, shots=num_shots, max_credits=15, backend=self.device) try: return { "result": self.device.run(qobj), "transpiled_circuit": experiment } except ApiError as e: if "Please wait for those jobs to finish or cancel a job." in str( e): print_stderr(str(e)) return { "result": ThinPromise(lambda: None), "transpiled_circuit": None } raise
def _run_and_measure( self, program: pq.Program, num_shots: int, measure_qubits: list, optimize, active_reset=False, ): program = program.copy() qubits = measure_qubits if measure_qubits is not None else program.get_qubits( ) # actively reset qubits at start if active_reset: program = pq.Program(pq.gates.RESET()) + program # add measurements everywhere ro = program.declare("ro", "BIT", len(qubits)) for i, q in enumerate(qubits): program.inst(pq.gates.MEASURE(q, ro[i])) program.wrap_in_numshots_loop(shots=num_shots) try: executable = self.device.compile(program, optimize=optimize) bitstring_array = self.device.run(executable=executable) except Exception as e: print_stderr(e) # we want to log, but not interrupt return { "result": ThinPromise(lambda: None), "transpiled_circuit": None } print_hl(program, color="grey") print_hl(executable.program, color="grey") bitstring_dict = {} for i, q in enumerate(qubits): bitstring_dict[q] = bitstring_array[:, i] return { "result": ThinPromise(lambda: bitstring_dict), "transpiled_circuit": executable.asdict(), }
def score(args): RUN_FOLDER = args.run_folder # benchmark to score BENCHMARK_ID = args.benchmark jobmanager_bench, _, slug_bench = obtain_jobmanager(BENCHMARK_ID, RUN_FOLDER, recreate_device=False) if not jobmanager_bench.done: print_stderr("benchmark not done yet") return BENCHMARK = slug_bench["additional_stored_info"]["benchmark"] # optional, a reference benchmark REFERENCE_ID = args.reference if REFERENCE_ID: jobmanager_ref, _, slug_ref = obtain_jobmanager(REFERENCE_ID, RUN_FOLDER, recreate_device=False) if not jobmanager_ref.done: print_stderr("reference not done yet") return if slug_ref["additional_stored_info"]["benchmark"] != BENCHMARK: print_stderr("benchmark and reference are not the same test") return jobmanager_bench.score( jobmanager_bench.collate_results(), jobmanager_ref.collate_results() if REFERENCE_ID else None, ) jobmanager_bench.print_gate_statistics()
def job_alive(self, promise, meta: dict): """ check whether we consider the job behind the promise alive on an IBM backend; however we should also check whether job_id is successful since only that makes a call to the cloud backend """ try: id = promise.job_id() except QiskitError as e: message = e.message.rstrip("\n .") if message.endswith("QUEUE_DISABLED"): print_stderr("The queue for this device is disabled.") return False elif message.endswith("NOT_CREDITS_AVALIABLES" ) or message.endswith("Error code: 3458"): print_stderr("You don't have enough credits to run this job.") return False raise # note that if this fails due to e.g. a TimeoutError # this does not mean that the job is broken; # it could e.g. be a network issue. We let that error propagate status = promise.status() print( f"The job with IBM ID {id} is reported to be in status: {status}") if status in [JobStatus.QUEUED, JobStatus.RUNNING, JobStatus.DONE]: return True elif status in [JobStatus.ERROR, JobStatus.CANCELLED, "FAILURE"]: return False # check whether status has been like this before if not "last-status" in meta or meta["last-status"]["status"] != status: meta["last-status"] = {"status": status, "time": utc_timestamp()} return True # calculate time difference; if below threshold all is ok age = time_elapsed(meta["last-status"]["time"]) if age <= self.MAX_JOB_AGE: return True # otherwise try to cancel old job print( f"The job with IBM ID {id} seems stuck in status: {status} for more than {age}, trying to cancel it." ) try: promise.cancel() del meta["last-status"] except QiskitError as e: print_stderr(e) finally: return False