class ProjectQContext(object): ''' Context for running circuits. Args: num_bit (int): number of bits in register. task ('ibm'|'draw'|'simulate'): task that decide the environment type. ibm_config (dict): extra arguments for IBM backend. ''' def __init__(self, num_bit, task, ibm_config=None): self.task = task self.num_bit = num_bit self.ibm_config = ibm_config def __enter__(self): ''' Enter context, Attributes: eng (MainEngine): main engine. backend ('graphical' or 'simulate'): backend used. qureg (Qureg): quantum register. ''' if self.task=='ibm': import projectq.setups.ibm else: import projectq.setups.default # create a main compiler engine with a specific backend: if self.task == 'draw': self.backend = CircuitDrawer() # locations = {0: 0, 1: 1, 2: 2, 3:3} # swap order of lines 0-1-2. # self.backend.set_qubit_locations(locations) elif self.task == 'simulate': print('ProjecQ simulation in training can be slow, since in scipy context, we cached a lot gates.') self.backend = Simulator() elif self.task == 'ibm': # choose device device = self.ibm_config.get('device', 'ibmqx2' if self.num_bit<=5 else 'ibmqx5') # check data if self.ibm_config is None: raise if device == 'ibmqx5': device_num_bit = 16 else: device_num_bit = 5 if device_num_bit < self.num_bit: raise AttributeError('device %s has not enough qubits for %d bit simulation!'%(device, self.num_bit)) self.backend = IBMBackend(use_hardware=True, num_runs=self.ibm_config['num_runs'], user=self.ibm_config['user'], password=self.ibm_config['password'], device=device, verbose=True) else: raise ValueError('engine %s not defined' % self.task) self.eng = MainEngine(self.backend) # initialize register self.qureg = self.eng.allocate_qureg(self.num_bit) return self def __exit__(self, exc_type, exc_val, traceback): ''' exit, meanwhile cheat and get wave function. Attributes: wf (1darray): for 'simulate' task, the wave function vector. res (1darray): for 'ibm' task, the measurements output. ''' if traceback is not None: return False if self.task == 'draw': self._viz_circuit() elif self.task == 'simulate': self.eng.flush() order, qvec = self.backend.cheat() self.wf = np.array(qvec) order = [order[i] for i in range(len(self.qureg))] self.wf = np.transpose(self.wf.reshape([2]*len(self.qureg), order='F'), axes=order).ravel(order='F') Measure | self.qureg self.eng.flush() elif self.task == 'ibm': Measure | self.qureg self.eng.flush() self.res = self.backend.get_probabilities(self.qureg) else: raise return self def _viz_circuit(self): Measure | self.qureg self.eng.flush() # print latex code to draw the circuit: s = self.backend.get_latex() # save graph to latex file os.chdir(TEX_FOLDER) with open(TEX_FILENAME, 'w') as f: f.write(s) # texfile = os.path.join(folder, 'circuit-%d.tex'%bench_id) pdffile = TEX_FILENAME[:-3]+'pdf' os.system('pdflatex %s'%TEX_FILENAME) openfile(pdffile)
def main(): args = _define_args() args = args.parse_args() _check(args) fin = args.infile fout = args.outfile engines = ibm.get_engine_list() # remove the CNot flipper if not args.ibm: engines = engines[:-2] + engines[-1:] print('Converting...') else: print('Converting for IBM Q Experience...') if args.on_hardware: print('We will run the converted code on the IBM device {}\n.'.format( args.ibm)) backend = IBMBackend(use_hardware=True, device=args.ibm, num_runs=args.n) elif args.s: print('We will run the converted code on the IBM simulator\n.') backend = IBMBackend(use_hardware=False, device=args.ibm, num_runs=args.n) else: # backend similar to IBMBackend creating qasm code but without running it backend = GetQASMBackend() eng = MainEngine(backend=backend, engine_list=engines) s = fin.read() fin.close() # parse input root = grammar.parse(s) # create visitor that transforms tree into gate list visitor = ToGateListVisitor() # pass root of parsed tree to visitor gate_list = visitor.visit(root) #gate_list=flatten_touples(gate_list) # create circuit from gate_list nb_qubits = build_circuit(gate_list, eng) # create qasm code qasm = get_qasm(eng, nb_qubits) if fout == sys.stdout: print(5 * '=' + ' OpenQASM code ' + 5 * '=') fout.write(qasm) if fout != sys.stdout: print('OpenQASM output saved to {}'.format(fout.name)) print() if hasattr(backend, 'get_probabilities'): print(5 * '=' + ' Results from {} run on hardware '.format(args.n) + 5 * '=') for k, v in sorted(backend.get_probabilities(qureg).items()): print('Probability for state |{}>: {}'.format(k, v))