def execute(self, inputParams): xacc_opts = inputParams['XACC'] acc_name = xacc_opts['accelerator'] if 'verbose' in xacc_opts and xacc_opts['verbose']: xacc.set_verbose(True) if 'Benchmark' not in inputParams: xacc.error( 'Invalid benchmark input - must have Benchmark description') if 'Circuit' not in inputParams: xacc.error( 'Invalid benchmark input - must have circuit description') self.qpu = xacc.getAccelerator(acc_name, xacc_opts) if 'Decorators' in inputParams: if 'readout_error' in inputParams['Decorators']: qpu = xacc.getAcceleratorDecorator('ro-error', qpu) provider = xacc.getIRProvider('quantum') if 'source' in inputParams['Circuit']: # here assume this is xasm always src = inputParams['Circuit']['source'] xacc.qasm(src) # get the name of the circuit circuit_name = None for l in src.split('\n'): if '.circuit' in l: circuit_name = l.split(' ')[1] self.circuit_name = circuit_name ansatz = xacc.getCompiled(circuit_name) opts = {'circuit': ansatz, 'accelerator': self.qpu} if 'qubit-map' in inputParams['Circuit']: raw_qbit_map = inputParams['Circuit']['qubit-map'] if not isinstance(raw_qbit_map, list): raw_qbit_map = ast.literal_eval(raw_qbit_map) self.qubit_map = raw_qbit_map opts['qubit-map'] = self.qubit_map self.qpt = xacc.getAlgorithm('qpt', opts) self.nq = ansatz.nLogicalBits() buffer = xacc.qalloc(ansatz.nLogicalBits()) self.qpt.execute(buffer) return buffer
# Allocate some qubits qbits = xacc.qalloc(4) # Create the H2 4 qubit hamiltonian # note, first run 'python3 -m xacc --benchmark-install chemistry' hamiltonianService = xacc.serviceRegistry.get_service('hamiltonian_generator', 'xaccKernelH2') obs = hamiltonianService.generate({}) # Create the UCC-1 ansatz ansatzService = xacc.serviceRegistry.get_service('ansatz_generator', 'ucc1') ucc1 = ansatzService.generate({'x-gates': [0, 1]}, 4) # Create the RDM Purification decorator error mitigation strategy # and give it the fermionic representation qpu_decorator = xacc.getAcceleratorDecorator('rdm-purification', qpu) qpu_decorator.initialize({'fermion-observable': obs}) # Let's use the NLOpt optimizer opt = xacc.getOptimizer('nlopt') # Create the VQE algorithm vqe = xacc.getAlgorithm( 'vqe', { 'ansatz': ucc1, 'accelerator': qpu_decorator, 'observable': obs, 'optimizer': opt }) # Execute
def execute(self, inputParams): xacc_opts = inputParams['XACC'] acc_name = xacc_opts['accelerator'] qpu = xacc.getAccelerator(acc_name, xacc_opts) if 'verbose' in xacc_opts and xacc_opts['verbose']: xacc.set_verbose(True) if 'Benchmark' not in inputParams: xacc.error('Invalid benchmark input - must have Benchmark description') if 'Observable' not in inputParams: xacc.error('Invalid benchmark input - must have Observable description') if 'Ansatz' not in inputParams: xacc.error('Invalid benchmark input - must have Ansatz circuit description') if 'Decorators' in inputParams: if 'readout_error' in inputParams['Decorators']: qpu = xacc.getAcceleratorDecorator('ro-error', qpu) H = None if inputParams['Observable']['name'] == 'pauli': obs_str = inputParams['Observable']['obs_str'] H = xacc.getObservable('pauli', obs_str) elif inputParams['Observable']['name'] == 'fermion': obs_str = inputParams['Observable']['obs_str'] H = xacc.getObservable('fermion', obs_str) elif inputParams['Observable']['name'] == 'psi4': opts = {'basis':inputParams['Observable']['basis'], 'geometry':inputParams['Observable']['geometry']} if 'fo' in inputParams['Observable'] and 'ao' in inputParams['Observable']: opts['frozen-spin-orbitals'] = ast.literal_eval(inputParams['Observable']['fo']) opts['active-spin-orbitals'] = ast.literal_eval(inputParams['Observable']['ao']) H = xacc.getObservable('psi4', opts) #print('Ham: ', H.toString()) buffer = xacc.qalloc(H.nBits()) optimizer = None if 'Optimizer' in inputParams: # check that values that can be ints/floats are opts = inputParams['Optimizer'] for k,v in inputParams['Optimizer'].items(): try: i = int(v) opts[k] = i continue except: pass try: f = float(v) opts[k] = f continue except: pass optimizer = xacc.getOptimizer(inputParams['Optimizer']['name'] if 'Optimizer' in inputParams else 'nlopt', opts) else: optimizer = xacc.getOptimizer('nlopt') provider = xacc.getIRProvider('quantum') if 'source' in inputParams['Ansatz']: # here assume this is xasm always src = inputParams['Ansatz']['source'] xacc.qasm(src) # get the name of the circuit circuit_name = None for l in src.split('\n'): if '.circuit' in l: circuit_name = l.split(' ')[1] ansatz = xacc.getCompiled(circuit_name) else: ansatz = provider.createInstruction(inputParams['Ansatz']['ansatz']) ansatz = xacc.asComposite(ansatz) alg = xacc.getAlgorithm(inputParams['Benchmark']['algorithm'], { 'ansatz': ansatz, 'accelerator': qpu, 'observable': H, 'optimizer': optimizer, }) alg.execute(buffer) return buffer
import xacc import numpy as np qpu = xacc.getAccelerator('aer', {'readout_error': True, 'shots': 4096,\ 'backend':'ibmq_20_tokyo'}) qbits = xacc.qalloc(3) layout = np.array([1, 2, 3], dtype=np.uintp) decorator = xacc.getAcceleratorDecorator('assignment-error-kernel', qpu, { 'gen-kernel': True, 'layout': layout }) xacc.qasm(''' .compiler xasm .circuit foo .qbit q H(q[0]); H(q[1]); CNOT(q[0], q[2]); CNOT(q[1], q[2]); Measure(q[0]); Measure(q[1]); Measure(q[2]); ''') ansatz = xacc.getCompiled('foo') decorator.execute(qbits, ansatz) print(qbits)
def execute(self, inputParams): """ This method is intended to be inherited by vqe and vqe_energy subclasses to allow algorithm-specific implementation. This superclass method adds extra information to the buffer and allows XACC settings options to be set before executing VQE. Parameters: inputParams : dictionary a dictionary of input parameters obtained from .ini file return QPU Accelerator buffer Options used (obtained from inputParams): 'qubit-map': map of logical qubits to physical qubits 'n-execs': number of sampler executions of measurements 'initial-parameters': list of initial parameters for the VQE algorithm 'restart-from-file': AcceleratorDecorator option to allow restart of VQE algorithm 'readout-error': AcceleratorDecorator option for readout-error mitigation """ m = xacc.HeterogeneousMap() if 'shots' in inputParams: m.insert('shots', int(inputParams['shots'])) if 'backend' in inputParams: m.insert('backend', inputParams['backend']) self.qpu = xacc.getAccelerator(inputParams['accelerator'], m) xaccOp = self.hamiltonian_generators[ inputParams['hamiltonian-generator']].generate(inputParams) self.ansatz = self.ansatz_generators[inputParams['name']].generate( inputParams, xaccOp.nBits()) if 'qubit-map' in inputParams: qubit_map = ast.literal_eval(inputParams['qubit-map']) xaccOp, self.ansatz, n_qubits = xaccvqe.mapToPhysicalQubits( xaccOp, self.ansatz, qubit_map) else: n_qubits = xaccOp.nBits() self.op = xaccOp self.n_qubits = n_qubits # create buffer, add some extra info (hamiltonian, ansatz-qasm, python-ansatz-qasm) self.buffer = xacc.qalloc(n_qubits) self.buffer.addExtraInfo('hamiltonian', self.op.toString()) self.buffer.addExtraInfo( 'ansatz-qasm', self.ansatz.toString().replace('\\n', '\\\\n')) pycompiler = xacc.getCompiler('pyxasm') # self.buffer.addExtraInfo('ansatz-qasm-py', '\n'.join(pycompiler.translate(self.ansatz).split('\n')[1:])) # heres where we can set up the algorithm Parameters # all versions of vqe require: Accelerator, Ansatz, Observable # pure-vqe requires Optimizer # energy calculation has optional Parameters - can be random self.vqe_options_dict = { 'accelerator': self.qpu, 'ansatz': self.ansatz, 'observable': self.op } # get optimizers for VQE # needs to check if optimizer is a python plugin # if not, use nlopt (with options) # so we pull 'optimizer-options' out if available # Optimizer-options needs to be passed to BOTH XACC Core optimizers and to python plugins # vqe_options_dict is used to initialize the algorithms self.optimizer = None self.optimizer_options = {} if 'optimizer-options' in inputParams: self.optimizer_options = ast.literal_eval( inputParams['optimizer-options']) # initial-parameters for optimizer (vqe) # parameters for vqe-energy if 'initial-parameters' in inputParams: self.optimizer_options['initial-parameters'] = ast.literal_eval( inputParams['initial-parameters']) if 'parameters' in inputParams: self.optimizer_options['parameters'] = ast.literal_eval( inputParams['parameters']) if 'nlopt-maxeval' in inputParams: self.optimizer_options['nlopt-maxeval'] = int( inputParams['nlopt-maxeval']) # check to see if optimizer is a python plugin # if it is, we do not put it in self.vqe_options_dict # if it is not, it is put there if 'optimizer' in inputParams: if inputParams['optimizer'] in self.vqe_optimizers: self.optimizer = self.vqe_optimizers[inputParams['optimizer']] else: self.optimizer = xacc.getOptimizer(inputParams['optimizer'], self.optimizer_options) else: self.optimizer = xacc.getOptimizer('nlopt', self.optimizer_options) # vqe.py then will check vqe_options_dict for optimizer; if it isn't there, run python optimizer # and of course if it is, we run with XACC self.buffer.addExtraInfo('accelerator', inputParams['accelerator']) # need to make sure the AcceleratorDecorators work correctly if 'n-execs' in inputParams: xacc.setOption('sampler-n-execs', inputParams['n-execs']) self.qpu = xacc.getAcceleratorDecorator('improved-sampling', self.qpu) if 'restart-from-file' in inputParams: xacc.setOption('vqe-restart-file', inputParams['restart-from-file']) self.qpu = xacc.getAcceleratorDecorator('vqe-restart', self.qpu) self.qpu.initialize() if 'readout-error' in inputParams and inputParams['readout-error']: self.qpu = xacc.getAcceleratorDecorator('ro-error', self.qpu) if 'rdm-purification' in inputParams and inputParams[ 'rdm-purification']: print("setting RDM Purification") self.qpu = xacc.getAcceleratorDecorator('rdm-purification', self.qpu) m = xacc.HeterogeneousMap() m.insert('fermion-observable', self.op) self.qpu.initialize(m) self.vqe_options_dict = { 'optimizer': self.optimizer, 'accelerator': self.qpu, 'ansatz': self.ansatz, 'observable': self.op } xacc.setOptions(inputParams)
def analyze(self, buffer, inputParams): """ This method is also to be inherited by vqe and vqe_energy subclasses to allow for algorithm-specific implementation. This superclass method always generates a .csv file with measured expectation values for each kernel and calculated energy of each iteration. Parameters: inputParams : dictionary a dictionary of input parameters obtained from .ini file buffer : XACC AcceleratorBuffer AcceleratorBuffer containing VQE results to be analyzed Options used (in inputParams): 'readout-error': generate .csv file with readout-error corrected expectation values and calculated energy for each kernel and iteration. 'richardson-extrapolation': run Richardson-Extrapolation on the resulting Accelerator buffer (generating 4 more .csv files of expectation values and energies) 'rich-extra-iter': the number of iterations of Richardson-Extrapolation """ ps = buffer.getAllUnique('parameters') timestr = time.strftime("%Y%m%d-%H%M%S") exp_csv_name = "%s_%s_%s_%s" % ( os.path.splitext(buffer.getInformation('file-name'))[0], buffer.getInformation('accelerator'), "exp_val_z", timestr) f = open(exp_csv_name + ".csv", 'w') exp_columns = [ c.getInformation('kernel') for c in buffer.getChildren('parameters', ps[0]) ] + ['<E>'] f.write(str(exp_columns).replace('[', '').replace(']', '') + '\n') for p in ps: energy = 0.0 for c in buffer.getChildren('parameters', p): exp = c.getInformation('exp-val-z') energy += exp * c.getInformation( 'coefficient') if c.hasExtraInfoKey('coefficient') else 0.0 f.write(str(exp) + ',') f.write(str(energy) + '\n') f.close() if 'readout-error' in inputParams: ro_exp_csv_name = "%s_%s_%s_%s" % ( os.path.splitext(buffer.getInformation('file-name'))[0], buffer.getInformation('accelerator'), "ro_fixed_exp_val_z", timestr) f = open(ro_exp_csv_name + '.csv', 'w') f.write(str(exp_columns).replace('[', '').replace(']', '') + '\n') for p in ps: energy = 0.0 for c in buffer.getChildren('parameters', p): exp = c.getInformation('ro-fixed-exp-val-z') energy += exp * c.getInformation( 'coefficient') if c.hasExtraInfoKey( 'coefficient') else 0.0 f.write(str(exp) + ',') f.write(str(energy) + '\n') f.close() if 'richardson-extrapolation' in inputParams and inputParams[ 'richardson-extrapolation']: from scipy.optimize import curve_fit import numpy as np angles = buffer.getInformation('vqe-angles') qpu = self.vqe_options_dict['accelerator'] self.vqe_options_dict[ 'accelerator'] = xacc.getAcceleratorDecorator( 'rich-extrap', qpu) self.vqe_options_dict['task'] = 'compute-energy' xaccOp = self.op self.vqe_options_dict['vqe-params'] = ','.join( [str(x) for x in angles]) fileNames = { r: "%s_%s_%s_%s" % (os.path.splitext(buffer.getInformation('file-name'))[0], buffer.getInformation('accelerator'), 'rich_extrap_' + str(r), timestr) + '.csv' for r in [1, 3, 5, 7] } nRE_Execs = 2 if not 'rich-extrap-iter' in inputParams else int( inputParams['rich-extrap-iter']) if nRE_Execs < 2: print( 'Richardson Extrapolation needs more than 1 execution. Setting to 2.' ) nRE_execs = 2 for r in [1, 3, 5, 7]: f = open(fileNames[r], 'w') xacc.setOption('rich-extrap-r', r) for i in range(nRE_Execs): richardson_buffer = qpu.createBuffer('q', self.n_qubits) results = xaccvqe.execute(xaccOp, richardson_buffer, **self.vqe_options_dict) ps = richardson_buffer.getAllUnique('parameters') for p in ps: f.write(str(p).replace('[', '').replace(']', '')) energy = 0.0 for c in richardson_buffer.getChildren( 'parameters', p): exp = c.getInformation( 'ro-fixed-exp-val-z') if c.hasExtraInfoKey( 'ro-fixed-exp-val-z' ) else c.getInformation('exp-val-z') energy += exp * c.getInformation('coefficient') f.write(',' + str(exp)) f.write(',' + str(energy) + '\n') f.close() nParams = len(ps[0]) columns = ['t{}'.format(i) for i in range(nParams)] kernelNames = [ c.getInformation('kernel') for c in buffer.getChildren('parameters', ps[0]) ] columns += kernelNames columns.append('E') dat = [ np.genfromtxt(fileNames[1], delimiter=',', names=columns), np.genfromtxt(fileNames[3], delimiter=',', names=columns), np.genfromtxt(fileNames[5], delimiter=',', names=columns), np.genfromtxt(fileNames[7], delimiter=',', names=columns) ] allExps = [{k: [] for k in kernelNames} for i in range(4)] allEnergies = [] temp = {r: [] for r in range(4)} for i in range(nRE_Execs): for r in range(4): for term in kernelNames: allExps[r][term].append(dat[r][term][i]) temp[r].append(dat[r]['E'][i]) evars = [np.std(temp[r]) for r in range(4)] xVals = [1, 3, 5, 7] avgExps = { k: [np.mean(allExps[r][k]) for r in range(4)] for k in kernelNames } varExps = { k: [np.std(allExps[r][k]) for r in range(4)] for k in kernelNames } energies = [np.mean(temp[r]) for r in range(4)] def linear(x, a, b): return a * x + b def exp(x, a, b): return a * np.exp(b * x) # + b def quad(x, a, b, c): return a * x * x + b * x + c print('\nnoisy energy: ', energies[0], '+-', evars[0]) res = curve_fit(linear, xVals, energies, [1, energies[0]], sigma=evars) print('\nrich linear extrap: ', res[0][1], '+- ', np.sqrt(np.diag(res[1])[1])) res_exp = curve_fit(exp, xVals, energies, [0, 0], sigma=evars) print('\nrich exp extrap: ', exp(0, res_exp[0][0], res_exp[0][1]), '+-', np.sqrt(np.diag(res_exp[1])[1])) res_q = curve_fit(quad, xVals, energies, [0, 0, 0], sigma=evars) print("\nrich quad extrap: ", quad(0, res_q[0][0], res_q[0][1], res_q[0][2]), "+-", np.sqrt(np.diag(res_q[1])[2]))
def execute(self, inputParams): """ This method is intended to be inherited by vqe and vqe_energy subclasses to allow algorithm-specific implementation. This superclass method adds extra information to the buffer and allows XACC settings options to be set before executing VQE. Parameters: inputParams : dictionary a dictionary of input parameters obtained from .ini file return QPU Accelerator buffer Options used (obtained from inputParams): 'qubit-map': map of logical qubits to physical qubits 'n-execs': number of sampler executions of measurements 'initial-parameters': list of initial parameters for the VQE algorithm 'restart-from-file': AcceleratorDecorator option to allow restart of VQE algorithm 'readout-error': AcceleratorDecorator option for readout-error mitigation """ self.qpu = xacc.getAccelerator(inputParams['accelerator']) xaccOp = self.hamiltonian_generators[ inputParams['hamiltonian-generator']].generate(inputParams) self.ansatz = self.ansatz_generators[inputParams['name']].generate( inputParams, xaccOp.nQubits()) if 'qubit-map' in inputParams: qubit_map = ast.literal_eval(inputParams['qubit-map']) xaccOp, self.ansatz, n_qubits = xaccvqe.mapToPhysicalQubits( xaccOp, self.ansatz, qubit_map) else: n_qubits = xaccOp.nQubits() self.op = xaccOp self.n_qubits = n_qubits self.buffer = self.qpu.createBuffer('q', n_qubits) self.buffer.addExtraInfo('hamiltonian', str(xaccOp)) self.buffer.addExtraInfo( 'ansatz-qasm', self.ansatz.toString('q').replace('\\n', '\\\\n')) pycompiler = xacc.getCompiler('xacc-py') self.buffer.addExtraInfo( 'ansatz-qasm-py', '\n'.join(pycompiler.translate('q', self.ansatz).split('\n')[1:])) self.optimizer = None self.optimizer_options = {} if 'optimizer' in inputParams: if inputParams['optimizer'] in self.vqe_optimizers: self.optimizer = self.vqe_optimizers[inputParams['optimizer']] if 'method' in inputParams: self.optimizer_options['method'] = inputParams['method'] if 'options' in inputParams: self.optimizer_options['options'] = ast.literal_eval( inputParams['options']) if 'user-params' in inputParams: self.optimizer_options['options'][ 'user_params'] = ast.literal_eval( inputParams['user-params']) else: xacc.setOption('vqe-backend', inputParams['optimizer']) else: xacc.info( "No classical optimizer specified. Setting to default XACC optimizer." ) self.buffer.addExtraInfo('accelerator', inputParams['accelerator']) if 'n-execs' in inputParams: xacc.setOption('sampler-n-execs', inputParams['n-execs']) self.qpu = xacc.getAcceleratorDecorator('improved-sampling', self.qpu) if 'restart-from-file' in inputParams: xacc.setOption('vqe-restart-file', inputParams['restart-from-file']) self.qpu = xacc.getAcceleratorDecorator('vqe-restart', self.qpu) self.qpu.initialize() if 'readout-error' in inputParams and inputParams['readout-error']: self.qpu = xacc.getAcceleratorDecorator('ro-error', self.qpu) if 'rdm-purification' in inputParams and inputParams[ 'rdm-purification']: self.qpu = xacc.getAcceleratorDecorator('rdm-purification', self.qpu) self.vqe_options_dict = { 'accelerator': self.qpu, 'ansatz': self.ansatz } if 'initial-parameters' in inputParams: self.vqe_options_dict['vqe-params'] = ','.join([ str(x) for x in ast.literal_eval(inputParams['initial-parameters']) ]) xacc.setOptions(inputParams)
nAngles = 10 # Get the local-ibm and tnqvm accelerators # and allocate some qubits for execution on each qpu = xacc.getAccelerator('aer', { 'shots': 1024, 'backend': 'ibmq_johannesburg', 'readout_error': True }) tnqvm = xacc.getAccelerator('tnqvm') buffer = xacc.qalloc(2) tnqvmBuffer = xacc.qalloc(2) # Turn on readout error correction by decorating # the local-ibm accelerator qpu = xacc.getAcceleratorDecorator('ro-error', qpu) # Construct the Hamiltonian ham = xacc.getObservable( 'pauli', '5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1') # Define the ansatz and decorate it to indicate # you'd like to run VQE @xacc.qpu(algo='energy', accelerator=qpu, observable=ham) def ansatz(buffer, t0): X(buffer[0]) Ry(buffer[1], t0) CNOT(buffer[1], buffer[0])
import xacc noiseModelJson = '{"errors": [{"type": "qerror", "operations": ["u1"], "instructions": [[{"name": "x", "qubits": [0]}], [{"name": "y", "qubits": [0]}], [{"name": "z", "qubits": [0]}], [{"name": "id", "qubits": [0]}]], "probabilities": [0.00025, 0.00025, 0.00025, 0.99925]}, {"type": "qerror", "operations": ["u2"], "instructions": [[{"name": "x", "qubits": [0]}], [{"name": "y", "qubits": [0]}], [{"name": "z", "qubits": [0]}], [{"name": "id", "qubits": [0]}]], "probabilities": [0.00025, 0.00025, 0.00025, 0.99925]}, {"type": "qerror", "operations": ["u3"], "instructions": [[{"name": "x", "qubits": [0]}], [{"name": "y", "qubits": [0]}], [{"name": "z", "qubits": [0]}], [{"name": "id", "qubits": [0]}]], "probabilities": [0.00025, 0.00025, 0.00025, 0.99925]}], "x90_gates": []}' qpu = xacc.getAccelerator('aer', { 'noise-model': noiseModelJson, 'shots': 4096 }) qpu = xacc.getAcceleratorDecorator('mitiq', qpu) q = xacc.qalloc(1) xacc.qasm('''.compiler xasm .circuit foo .parameters x .qbit q for (int i = 0; i < 10; i++) { X(q[0]); } Measure(q[0]); ''') foo = xacc.getCompiled('foo') qpu.execute(q, foo) print(q) print(q.getExpectationValueZ())