def __call__(self, *args, **kwargs): super().__call__(*args, **kwargs) def getParams(params): return ','.join(map(str, params)) execParams = {'accelerator': self.qpu, 'ansatz': self.compiledKernel, 'task': 'vqe'} obs = self.kwargs['observable'] ars = list(args) if not isinstance(args[0], xacc.AcceleratorBuffer): raise RuntimeError( 'First argument of an xacc kernel must be the Accelerator Buffer to operate on.') buffer = ars[0] ars = ars[1:] if len(ars) > 0: arStr = getParams(ars) execParams['vqe-params'] = arStr # optimizer given if 'optimizer' in self.kwargs: opt_name = self.kwargs['optimizer'] optimizer_args = {} # get optimizer from available vqe_optimization services if opt_name not in self.vqe_optimizers: xacc.info("The {} 'vqe_optimization' service is not available.".format(opt_name)) exit(1) else: optimizer = self.vqe_optimizers[opt_name] # get all the options to pass to optimizer if 'options' in self.kwargs: optimizer_args = self.kwargs['options'] # call optimize() method of optimizer optimizer.optimize(obs, buffer, optimizer_args, execParams) else: vqe.execute(obs, buffer, **execParams) return
def __call__(self, *args, **kwargs): super().__call__(*args, **kwargs) def getParams(params): return ','.join(map(str, params)) execParams = {'accelerator': self.qpu, 'ansatz': self.compiledKernel, 'task': 'compute-energy'} obs = self.kwargs['observable'] ars = list(args) if not isinstance(args[0], xacc.AcceleratorBuffer): raise RuntimeError( 'First argument of an xacc kernel must be the Accelerator Buffer to operate on.') buffer = ars[0] ars = ars[1:] if len(ars) > 0: arStr = getParams(ars) execParams['vqe-params'] = arStr vqe.execute(obs, buffer, **execParams) return
def execute(self, inputParams): """ Inherited method with algorithm-specific implementation Parameters: inputParams - a dictionary of input parameters obtained from .ini file - sets XACC VQE task to 'compute-energy' - executes a parameter-sweep """ super().execute(inputParams) pi = 3.141592653589793 self.vqe_options_dict['task'] = 'compute-energy' if inputParams['upper-bound'] == 'pi': up_bound = pi else: up_bound = ast.literal_eval(inputParams['upper-bound']) if inputParams['lower-bound'] == '-pi': low_bound = -pi else: low_bound = ast.literal_eval(inputParams['lower-bound']) num_params = ast.literal_eval(inputParams['num-params']) self.energies = [] self.angles = [] for param in self.linspace(low_bound, up_bound, num_params): self.angles.append(param) self.vqe_options_dict['vqe-params'] = str(param) energy = xaccvqe.execute(self.op, self.buffer, **self.vqe_options_dict).energy if 'rdm-purification' in self.qpu.name(): p = self.buffer.getAllUnique('parameters') ind = len(p) - 1 children = self.buffer.getChildren('parameters', p[ind]) energy = children[1].getInformation('purified-energy') self.energies.append(energy) self.buffer.addExtraInfo('vqe-energies', self.energies) self.buffer.addExtraInfo('vqe-angles', self.angles) self.buffer.addExtraInfo('vqe-energy', min(self.energies)) return self.buffer
def energy(self, params): pStr = ",".join(map(str, params)) self.execParams['vqe-params'] = pStr e = vqe.execute(self.obs, self.buffer, **self.execParams).energy if 'rdm-purification' in self.execParams['accelerator'].name(): t = self.buffer.getAllUnique('parameters') ind = len(t) - 1 children = self.buffer.getChildren('parameters', t[ind]) e = children[1].getInformation('purified-energy') self.angles.append(self.execParams['vqe-params']) self.energies.append(e) fileName = ".persisted_buffer_%s" % (self.buffer.getInformation('accelerator')) if self.buffer.hasExtraInfoKey('accelerator') \ else ".persisted_buffer_%s" % (self.execParams['accelerator'].name()) file = open(fileName + '.ab', 'w') file.write(str(self.buffer)) file.close() return e
def execute(self, inputParams): """ Inherited method with algorithm-specific implementation Parameters: inputParams - a dictionary of input parameters obtained from .ini file """ super().execute(inputParams) self.vqe_options_dict['task'] = 'vqe' if self.optimizer is not None: self.optimizer.optimize(self.op, self.buffer, self.optimizer_options, self.vqe_options_dict) else: result = xaccvqe.execute(self.op, self.buffer, **self.vqe_options_dict) return self.buffer
def testExecuteVQE(self): src = """__qpu__ kernel() { 0.7137758743754461 -1.252477303982147 0 1 0 0 0.337246551663004 0 1 1 1 1 0 0 0 0.0906437679061661 0 1 1 1 3 0 2 0 0.0906437679061661 0 1 2 1 0 0 2 0 0.3317360224302783 0 1 2 1 2 0 0 0 0.0906437679061661 0 1 3 1 1 0 2 0 0.3317360224302783 0 1 3 1 3 0 0 0 0.337246551663004 1 1 0 1 0 0 1 0 0.0906437679061661 1 1 0 1 2 0 3 0 -1.252477303982147 1 1 1 0 0.0906437679061661 1 1 2 1 0 0 3 0 0.3317360224302783 1 1 2 1 2 0 1 0 0.0906437679061661 1 1 3 1 1 0 3 0 0.3317360224302783 1 1 3 1 3 0 1 0 0.3317360224302783 2 1 0 1 0 0 2 0 0.0906437679061661 2 1 0 1 2 0 0 0 0.3317360224302783 2 1 1 1 1 0 2 0 0.0906437679061661 2 1 1 1 3 0 0 0 -0.4759344611440753 2 1 2 0 0.0906437679061661 2 1 3 1 1 0 0 0 0.3486989747346679 2 1 3 1 3 0 2 0 0.3317360224302783 3 1 0 1 0 0 3 0 0.0906437679061661 3 1 0 1 2 0 1 0 0.3317360224302783 3 1 1 1 1 0 3 0 0.0906437679061661 3 1 1 1 3 0 1 0 0.0906437679061661 3 1 2 1 0 0 1 0 0.3486989747346679 3 1 2 1 2 0 3 0 -0.4759344611440753 3 1 3 0 }""" op = vqe.compile(src) buffer = xacc.getAccelerator('tnqvm').createBuffer('q',4) self.assertAlmostEqual(vqe.execute(op, buffer, **{'task':'vqe', 'n-electrons':2}).energy, -1.13727, places=5)
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]))