예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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)
예제 #7
0
    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]))