def visit_Parameter(self, param: core.Parameter): if param.name in self.arguments: arg = self.arguments[param.name] # This check will basically always pass as Jaqal has no # way of type annotating macro arguments. param.validate(arg) return arg else: return param
def test_build_native_gate(self): name = randomize.random_identifier() parameters = [Parameter("a", ParamType.INT), Parameter("b", ParamType.FLOAT)] gate_def = GateDefinition(name, parameters=parameters) native_gates = {name: gate_def} a = 5 b = 1.234 sexpr = ("gate", name, a, b) exp_value = gate_def(a, b) act_value = build(sexpr, native_gates) self.assertEqual(exp_value, act_value)
def test_build_gate_with_constant(self): gate_def = GateDefinition("g", [Parameter("p", None)]) sexpr = ("circuit", ("let", "a", 1), ("gate", "g", "a")) exp_value = gate_def(Constant("a", 1)) circuit = build(sexpr, inject_pulses={"g": gate_def}) act_value = circuit.body.statements[0] self.assertEqual(exp_value, act_value)
def test_pass_through_core_type(self): test_values = [ Parameter("foo", None), Register("r", 3), ] for value in test_values: self.assertEqual(value, build(value))
def test_unnormalized_native_gates(self): """Test using native gates that are not a dictionary.""" gate_def = GateDefinition("g", [Parameter("p", None)]) sexpr = ("circuit", ("gate", "g", 0)) exp_value = gate_def(0) circuit = build(sexpr, inject_pulses=[gate_def]) act_value = circuit.body.statements[0] self.assertEqual(exp_value, act_value)
def test_build_macro_with_premade_parameters(self): param_ident = randomize.random_identifier() param = Parameter(param_ident, None) macro_ident = randomize.random_identifier() sexpr = ("macro", macro_ident, param, ("sequential_block",)) exp_value = core.Macro(macro_ident, [param]) act_value = build(sexpr) self.assertEqual(exp_value, act_value)
def make_slice_component(self, arg): if isinstance(arg, int): return arg elif isinstance(arg, str): return Parameter(arg, None) elif arg is None: return None elif isinstance(arg, AnnotatedValue): return arg else: raise ValueError(f"Cannot make slice component from {arg}")
def test_build_macro_definition(self): gate_def = GateDefinition("foo", parameters=[Parameter("x", None)]) sexpr = ( "macro", "bar", "a", "b", ("sequential_block", ("gate", "foo", "a"), ("gate", "foo", "b")), ) act_value = build(sexpr, inject_pulses={"foo": gate_def}) exp_value = core.Macro( "bar", parameters=[Parameter("a", None), Parameter("b", None)] ) exp_value.body.statements.append( core.GateStatement(gate_def, parameters={"x": Parameter("a", None)}) ) exp_value.body.statements.append( core.GateStatement(gate_def, parameters={"x": Parameter("b", None)}) ) self.assertEqual(exp_value, act_value)
def make_argument_object(self, arg): """Format an argument as the GateStatement constructor expects it.""" if isinstance(arg, Number): return arg elif isinstance(arg, tuple): return self.make_qubit(*arg) elif isinstance(arg, str): return Parameter(arg, None) elif isinstance(arg, NamedQubit): return arg elif isinstance(arg, AnnotatedValue): return arg else: raise TypeError(f"Cannot make an argument out of {arg}")
def make_random_parameter(name=None, allowed_types=None, return_params=False): """Return a parameter with a random type and name.""" if name is None: name = random_identifier() if allowed_types is None: allowed_types = ParamType.types param_type = random.choice(allowed_types) if param_type not in ParamType: raise ValueError(f"Unknown parameter type {param_type}") param = Parameter(name, param_type) if not return_params: return param else: return param, name, param_type
def test_build_circuit(self): """Build a circuit with as many features as possible.""" # We've already built a circuit elsewhere but this test tries to tie everything in together. gate_def = GateDefinition("g", [Parameter("p", None)]) native_gates = {"g": gate_def} sexpr = ( "circuit", ("register", "r", 7), ("map", "q", "r"), ("let", "x", 0), ("macro", "foo", "a", ("sequential_block", ("gate", "g", "a"))), ("gate", "foo", "x"), ("loop", 5, ("sequential_block", ("gate", "g", 3))), ("parallel_block", ("gate", "g", 0), ("gate", "g", 1)), ) act_value = build(sexpr, inject_pulses=native_gates) r = Register("r", 7) q = Register("q", alias_from=r) x = Constant("x", 0) foo = core.Macro("foo", parameters=[Parameter("a", None)]) foo.body.statements.append(gate_def(Parameter("a", None))) exp_value = core.Circuit(native_gates=native_gates) exp_value.registers[r.name] = r exp_value.registers[q.name] = q exp_value.constants[x.name] = x exp_value.macros[foo.name] = foo exp_value.body.statements.append(foo(x)) loop_block = core.BlockStatement(statements=[gate_def(3),]) loop = core.LoopStatement(5, loop_block) exp_value.body.statements.append(loop) parallel_block = core.BlockStatement(parallel=True) parallel_block.statements.append(gate_def(0)) parallel_block.statements.append(gate_def(1)) exp_value.body.statements.append(parallel_block) self.assertEqual(exp_value, act_value)
def test_add_macro_to_circuit(self): foo_def = core.GateDefinition("foo", parameters=[Parameter("x", None)]) native_gates = {"foo": foo_def} block = core.circuitbuilder.SequentialBlockBuilder() block.gate("foo", "a") builder = core.circuitbuilder.CircuitBuilder(native_gates=native_gates) builder.macro("my_macro", ["a"], body=block) self.run_test( ( "circuit", ("macro", "my_macro", "a", ("sequential_block", ("gate", "foo", "a"))), ), builder, native_gates=native_gates, )
def test_use_macro_gate(self): g_def = core.GateDefinition("g", [Parameter("p0", None)]) native_gates = {"g": g_def} builder = core.circuitbuilder.CircuitBuilder(native_gates=native_gates) block = core.circuitbuilder.SequentialBlockBuilder() block.gate("g", "a") builder.macro("foo", ["a"], block) builder.gate("foo", 1) self.run_test( ( "circuit", ("macro", "foo", "a", ("sequential_block", ("gate", "g", "a"))), ("gate", "foo", 1), ), builder, native_gates=native_gates, )
def make_parameter(self, name=None, index=None, kind=None): if name is None: if index is None: raise ValueError("Provide either name or index to Parameter") name = str(index) return Parameter(name, kind)
[np.cos(rotation_angle / 2), -np.sin(rotation_angle / 2)], [np.sin(rotation_angle / 2), np.cos(rotation_angle / 2)], ]) def U_Rz(rotation_angle): return np.array([[1, 0], [0, np.exp(1j * rotation_angle)]]) ACTIVE_NATIVE_GATES = ( BusyGateDefinition("prepare_all"), GateDefinition( "R", [ Parameter("q", ParamType.QUBIT), Parameter("axis-angle", ParamType.FLOAT), Parameter("rotation-angle", ParamType.FLOAT), ], ideal_unitary=U_R, ), GateDefinition( "Rx", [Parameter("q", ParamType.QUBIT), Parameter("angle", ParamType.FLOAT)], ideal_unitary=U_Rx, ), GateDefinition( "Ry", [Parameter("q", ParamType.QUBIT), Parameter("angle", ParamType.FLOAT)],