Commit d11dfd22 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

implement compute action uncompute at python level. very simple, just...


implement compute action uncompute at python level. very simple, just translates with compute to compute{ and with action to }action{ and finishes off the trailing rbrace

Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 5dcf66d8
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -216,8 +216,9 @@ std::string run_token_collector(
      // must open scope
      if (Toks[i].isNot(clang::tok::l_brace)) {
        xacc::error(
            "Invalid decompose statement, must be of form decompose "
            "{...} (...); with args in parenthesis being optional");
            "Invalid compute statement, must be of form decompose "
            "{...} (...); with args in parenthesis being optional: " +
            PP.getSpelling(Toks[i]));
      }

      // skip l_brace
@@ -260,7 +261,8 @@ std::string run_token_collector(
      src_to_prepend = src_code;

      code_ss << "::quantum::qrt_impl->__begin_mark_segment_as_compute();\n";
      code_ss << internal_kernel_function_name << "(parent_kernel, " << program_parameters[0];
      code_ss << internal_kernel_function_name << "(parent_kernel, "
              << program_parameters[0];
      for (int i = 1; i < program_parameters.size(); i++) {
        code_ss << ", " << program_parameters[i];
      }
+44 −0
Original line number Diff line number Diff line
from qcor import *
import numpy as np

@qjit 
def hf(q :qreg):
    X(q[0])
    X(q[2])

@qjit
def ucc1(q : qreg, x : float):
    with compute:
        Rx(q[0], np.pi/2.)
        for i in range(3):
            H(q[i+1])
        for i in range(3):
            CX(q[i], q[i+1])
    with action:
        Rz(q[3], x)

@qjit 
def ansatz(q : qreg, x : float):
    hf(q)
    ucc1(q, x)

@qjit
def test_ctrl(q: qreg, d : float):
    ucc1.ctrl(q[4], q, d)

H = createOperator("pyscf", {"basis": "sto-3g", "geometry":'''H  0.000000   0.0      0.0
H   0.0        0.0  .7474'''})

objective = createObjectiveFunction(ansatz, H, 1)
optimizer = createOptimizer("nlopt", {"maxeval": 20})

optval, opt_params = optimizer.optimize(objective)

print("energy = {}".format(optval))

print('\nAnsatz:')
ansatz.print_kernel(qalloc(4), 2.2)

print('\nCtrl-UCC1:')
qq = qalloc(5)
test_ctrl.print_kernel(qq, 2.2)
 No newline at end of file
+42 −0
Original line number Diff line number Diff line
@@ -332,6 +332,48 @@ class qjit(object):
                    fbody_src = fbody_src.replace(
                        total_decompose_code, new_src)

        if 'with compute' in fbody_src:
            # All we really should need to do is 
            # convert with compute to compute { 
            # and with action to } action {
            # then close with a } when we 
            # hit a new col location
            
            assert(fbody_src.count('with compute') == fbody_src.count('with action'))

            # split the function into lines
            lines = fbody_src.split('\n')
            new_src = ''
            in_action_block = False
            in_compute_block = False
            action_col, compute_col = (0, 0)
            for line in lines:
                current_col = sum(1 for _ in itertools.takewhile(str.isspace, line)) 
                if in_action_block and current_col <= action_col:
                    new_src += '}\n'

                if in_compute_block and current_col <= compute_col:
                    # here we have just dropped out of compute col
                    if 'with action' not in line:
                        print('After compute block, you must provide the action block.')
                        exit(1)

                if 'with compute' in line:
                    in_action_block = False
                    in_compute_block = True
                    compute_col = sum(1 for _ in itertools.takewhile(str.isspace, line))+1
                    new_src += 'compute {\n'
                elif 'with action' in line:
                    in_action_block = True
                    in_compute_block = False
                    action_col = sum(1 for _ in itertools.takewhile(str.isspace, line)) 
                    new_src += '} action {\n'
                else:
                    new_src += line + '\n'
                
            # update the source code
            fbody_src = new_src

        # Users must provide arg types, if not we throw an error
        if not self.type_annotations or len(self.arg_names) != len(self.type_annotations):
            print('Error, you must provide type annotations for qcor quantum kernels.')