def mapToPhysicalQubits(op, ansatz, logical2PhysicalMap): n_qubits = max(logical2PhysicalMap) + 1 ir = op.toXACCIR() xacc.setOption('qubit-map', ','.join([str(i) for i in logical2PhysicalMap])) irp = xacc.getIRPreprocessor('qubit-map-preprocessor') irp.process(ir) ham = PauliOperator() ham.fromXACCIR(ir) ansatzir = xacc.gate.createIR() ansatzir.addKernel(ansatz) irp.process(ansatzir) xacc.unsetOption('qubit-map') return ham, ansatz, n_qubits
# logging.getLogger().setLevel(logging.DEBUG) # requests_log = logging.getLogger("requests.packages.urllib3") # requests_log.setLevel(logging.DEBUG) # requests_log.propagate = True # requests.get('https://httpbin.org/headers') # File names to pass in for training and testing data train_file = os.path.join('nist_data/optdigits.tra') test_file = os.path.join('nist_data/optdigits.tes') # Initialize the xacc framework xacc.Initialize() # Get the XACC D-Wave accelerator dwave = xacc.getAccelerator('dwave') # Select which D-Wave solver to use xacc.setOption('dwave-solver', 'DW_2000Q_VFYC_2_1') # Create an AcceleratorBuffer for use in the XACC D-Wave accelerator buffer = dwave.createBuffer("buffer") # Add embedding to AcceleratorBuffer f = open('embedding.txt', 'r') embedding = ast.literal_eval(f.read()) f.close() buffer.addExtraInfo('embedding', embedding) # Specify the settings for the algorithm execution # These can also be passed directly into the xacc.qpu() decorator as keyword arguments # an optional argument for naming the output buffer file # is 'output': 'name_of_file' (no file extension) settings = {'algo': "mnist_digit_train", 'accelerator': dwave, 'train_data': train_file,
def __call__(self, *args, **kwargs): super().__call__(*args, **kwargs) self.initial_rbm = True self.buffer = args[0] self.embedding = self.buffer.getInformation('embedding') # Get the training parameters (rate, num_epochs, batch_size, momentum) self.learn_rate = self.kwargs['rate'] self.num_epochs = self.kwargs['num_epochs'] self.momentum = self.kwargs['momentum'] self.batch_size = self.kwargs['batch_size'] self.num_classes = self.kwargs['max_classes'] self.train_steps = self.kwargs['train_steps'] if 'chain-strength' in self.kwargs: xacc.setOption('chain-strength', self.kwargs['chain_strength']) if 'num_samples' in self.kwargs: xacc.setOption('dwave-num-reads', self.kwargs['num_samples']) # Get parameterized DWK self.rbm_function = self.compiledKernel # Might be a better way to get these values, but this is what I'm shooting for right now self.numV = 0 self.numH = 0 self.numW = 0 for inst in self.rbm_function.getParameters(): if 'v' in inst: self.numV += 1 if 'h' in inst: self.numH += 1 if 'w' in inst: self.numW += 1 # Initializing the weights from a random normal distribution # Initializing the hidden and visible biases to be zero self.weights = np.random.normal(0.01, 1.0, (self.numV, self.numH)) self.visible_bias = np.zeros((1, self.numV)) self.hidden_bias = np.zeros((1, self.numH)) tic = time.clock() self.data, self.n_evts = self.readTrainData(self.kwargs['train_data']) self.data = self.batchData(self.data, self.batch_size) for epoch in range(self.num_epochs): train_step = 0 for batch in self.data: xacc.info("Train Step {}".format(train_step)) if train_step >= self.train_steps > -1: break # get data expectation values dataExpW, dataExpV, dataExpH = self.getDataExpectations(batch) # set the RBM self.setRBM() training_buffer = self.qpu.createBuffer("buffer") training_buffer.addExtraInfo('embedding', self.embedding) # Execute the RBM with the new parameters self.executeRBM(training_buffer) # Get the expectation values from the D-Wave execution modelExpW, modelExpV, modelExpH = self.getExpectations() # Update the parameters for this batch self.updateParameters(dataExpW, modelExpW, dataExpV, modelExpV, dataExpH, modelExpH) train_step += 1 self.buffer.addExtraInfo("rbm_visible", self.visible_bias.flatten().tolist()) self.buffer.addExtraInfo("rbm_hidden", self.hidden_bias.flatten().tolist()) self.buffer.addExtraInfo("rbm_weights", self.weights.flatten().tolist()) toc = time.clock() training_time = toc - tic if 'test_data' in self.kwargs: self.test_data, self.test_targets, n_tests = self.readTestData( self.kwargs['test_data']) self.test_data = self.batchData(self.test_data, self.batch_size) evals = np.zeros((n_tests, self.num_classes)) truth_vals = np.zeros(n_tests) for digit in range(self.num_classes): w = np.reshape( np.array(self.buffer.getInformation("rbm_weights")), (self.numV, self.numH)) v = np.reshape( np.array(self.buffer.getInformation("rbm_visible")), (1, self.numV)) h = np.reshape( np.array(self.buffer.getInformation("rbm_hidden")), (1, self.numH)) count = 0 for i, batch in enumerate(self.test_data): Fv = self.freeEnergy(batch, w, v, h) targets = np.reshape(self.test_targets[i], (-1, )) ll = list(zip(targets, Fv)) for j, item in enumerate(ll): idx = i * self.batch_size + j evals[idx, digit] = item[1] if digit == 0: truth_vals[idx] = item[0] softmax = np.exp(-evals) / sum(np.exp(-evals)) predictions = np.argmax(softmax, axis=1) accuracy = np.sum(predictions == truth_vals) / len(truth_vals) self.buffer.addExtraInfo('accuracy', str(accuracy)) timestr = time.strftime("%Y%m%d-%H%M%S") self.buffer.addExtraInfo("training-time", training_time) print("Finished Training") print("Accuracy: ", self.buffer.getInformation('accuracy')) print("Training Time: ", self.buffer.getInformation('training-time')) output_name = self.kwargs[ 'output'] + '.ab' if 'output' in self.kwargs else "trained-rbm-buffer-{}.ab".format( timestr) f = open(output_name, "w") f.write(str(self.buffer)) f.close() return
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)
from xaccvqe import PauliOperator xacc.Initialize(['--compiler', 'quil']) #ibm = xacc.getAccelerator('ibm') tnqvm = xacc.getAccelerator('tnqvm') buffer = tnqvm.createBuffer('q', 2) ham = PauliOperator(5.906709445) + \ PauliOperator({0:'X',1:'X'}, -2.1433) + \ PauliOperator({0:'Y',1:'Y'}, -2.1433) + \ PauliOperator({0:'Z'}, .21829) + \ PauliOperator({1:'Z'}, -6.125) xacc.setOption('ibm-shots', '8192') #xacc.setOption('vqe-backend','vqe-bayesopt') #xacc.setOption('bo-n-iter','20') @xaccvqe.qpu.vqe(accelerator=tnqvm, observable=ham) def ansatz(buffer, t0): X(0) Ry(t0, 1) CNOT(1, 0) # Run VQE with given ansatz kernel initAngle = .5 ansatz(buffer, initAngle)
import xaccvqe from xaccvqe import PauliOperator import numpy as np xacc.Initialize() tnqvm = xacc.getAccelerator('tnqvm') buffer = tnqvm.createBuffer('q', 2) ham = PauliOperator(5.906709445) + \ PauliOperator({0:'X',1:'X'}, -2.1433) + \ PauliOperator({0:'Y',1:'Y'}, -2.1433) + \ PauliOperator({0:'Z'}, .21829) + \ PauliOperator({1:'Z'}, -6.125) xacc.setOption('itensor-svd-cutoff', '1e-16') # Hardware Efficient Ansatz xacc kernel @xaccvqe.qpu.energy(accelerator=tnqvm, observable=ham) def ansatz(buffer, *args): xacc(hwe, layers=2, n_qubits=2, connectivity='[[0,1]]') # XACC Kernels can display number of required nParameters # and be persisted to qasm string print(ansatz.nParameters()) print(ansatz.getFunction().toString('q')) # Generate an initial random set of vqe params # of the correct number of parameters and execute