コード例 #1
0
ファイル: test_get_locations.py プロジェクト: BQSKit/qfast
    def test_topology_get_locations_2 ( self ):
        cgraph = [ (0, 1), (1, 2), (2, 3) ]
        t = Topology( 4, cgraph )
        l = t.get_locations( 3 )

        self.assertTrue( len( l ) == 2 )
        self.assertTrue( (0, 1, 2) in l )
        self.assertTrue( (1, 2, 3) in l )
コード例 #2
0
ファイル: test_get_locations.py プロジェクト: BQSKit/qfast
    def test_topology_get_locations_3 ( self ):
        t = Topology( 4 )
        l = t.get_locations( 3 )

        self.assertTrue( len( l ) == 4 )
        self.assertTrue( (0, 1, 2) in l )
        self.assertTrue( (0, 1, 3) in l )
        self.assertTrue( (0, 2, 3) in l )
        self.assertTrue( (1, 2, 3) in l )
コード例 #3
0
    def test_decomposer_constructor_valid ( self ):
        valid_utry = np.identity( 8 )
        valid_target_gate_size = 2
        valid_model = "PermModel"
        valid_optimizer = "LBFGSOptimizer"
        valid_hierarchy_fn = lambda x : 2
        valid_topology  = Topology( 3, [ (0, 1), (1, 2) ] )

        decomposer = Decomposer( valid_utry, valid_target_gate_size,
                                 valid_model, valid_optimizer,
                                 valid_hierarchy_fn, valid_topology )
        
        self.assertTrue( np.allclose( decomposer.utry, valid_utry ) )
        self.assertTrue( decomposer.num_qubits == 3 )
        self.assertTrue( decomposer.target_gate_size == 2 )
        self.assertTrue( decomposer.hierarchy_fn(2112) == 2 )
        
        model = decomposer.model.__name__
        optimizer = decomposer.optimizer.__name__

        self.assertTrue( model == valid_model )
        self.assertTrue( optimizer == valid_optimizer )

        for link in valid_topology.coupling_graph:
            self.assertTrue( link in decomposer.topology.coupling_graph )

        self.assertTrue( len( decomposer.topology.coupling_graph ) == 2 )
コード例 #4
0
ファイル: test_constructor.py プロジェクト: BQSKit/qfast
    def test_topology_constructor_cgraph ( self ):
        cgraph = [ (0, 1), (1, 2), (2, 3) ]
        t = Topology( 4, cgraph )

        self.assertTrue( len( t.coupling_graph ) == 3 )
        for link in cgraph:
            self.assertTrue( link in t.coupling_graph )
コード例 #5
0
ファイル: test_get_locations.py プロジェクト: BQSKit/qfast
    def test_topology_get_locations_invalid ( self ):
        cgraph = [ (0, 1), (1, 2), (2, 3) ]
        t = Topology( 4, cgraph )

        self.assertRaises( ValueError, t.get_locations, 5 )
        self.assertRaises( ValueError, t.get_locations, 0 )
        self.assertRaises( ValueError, t.get_locations, -2 )
        self.assertRaises( TypeError, t.get_locations, "a" )
コード例 #6
0
ファイル: test_constructor.py プロジェクト: BQSKit/qfast
    def test_topology_constructor_alltoall ( self ):
        t = Topology( 2 )
        self.assertTrue( len( t.coupling_graph ) == 1 )
        self.assertTrue( (0, 1) in t.coupling_graph )

        t = Topology( 3 )
        self.assertTrue( len( t.coupling_graph ) == 3 )
        self.assertTrue( (0, 1) in t.coupling_graph )
        self.assertTrue( (0, 2) in t.coupling_graph )
        self.assertTrue( (1, 2) in t.coupling_graph )

        t = Topology( 4 )
        self.assertTrue( len( t.coupling_graph ) == 6 )
        self.assertTrue( (0, 1) in t.coupling_graph )
        self.assertTrue( (0, 2) in t.coupling_graph )
        self.assertTrue( (0, 3) in t.coupling_graph )
        self.assertTrue( (1, 2) in t.coupling_graph )
        self.assertTrue( (1, 3) in t.coupling_graph )
        self.assertTrue( (2, 3) in t.coupling_graph )
コード例 #7
0
ファイル: test_instantiate.py プロジェクト: BQSKit/qfast
    def test_instantiater_instantiate_invalid ( self ):
        valid_tool = "QSearchTool"
        valid_topology = Topology( 3, None )
        instantiater = Instantiater( valid_tool, valid_topology )

        test_0 = 0
        test_1 = "a"
        test_2 = ( 0, 1 )
        test_3 = ( self.CNOT, 0 )
        test_4 = ( self.CNOT, ( 0, 1 ) )
        test_5 = [ ( self.CNOT, ( 0, 1 ) ) ]
        
        self.assertRaises( TypeError, instantiater.instantiate, test_0 )
        self.assertRaises( TypeError, instantiater.instantiate, test_1 )
        self.assertRaises( TypeError, instantiater.instantiate, test_2 )
        self.assertRaises( TypeError, instantiater.instantiate, test_3 )
        self.assertRaises( TypeError, instantiater.instantiate, test_4 )
        self.assertRaises( TypeError, instantiater.instantiate, test_5 )
コード例 #8
0
ファイル: test_instantiate.py プロジェクト: BQSKit/qfast
    def test_instantiater_instantiate_valid ( self ):
        valid_tool = "QSearchTool"
        valid_topology = Topology( 3, None )
        instantiater = Instantiater( valid_tool, valid_topology )

        qasm_list = instantiater.instantiate( [ gate.Gate( self.CNOT, (0, 1) ) ] )

        self.assertTrue( isinstance( qasm_list, list ) )
        self.assertTrue( len( qasm_list ) == 1 )

        self.assertTrue( isinstance( qasm_list[0], tuple ) )
        self.assertTrue( len( qasm_list[0] ) == 2 )

        self.assertTrue( isinstance( qasm_list[0][0], str ) )
        self.assertTrue( "OPENQASM" in qasm_list[0][0] )
        self.assertTrue( "cx" in qasm_list[0][0] )
        self.assertTrue( "qreg q[2]" in qasm_list[0][0] )

        self.assertTrue( qasm_list[0][1] == (0, 1) )
コード例 #9
0
ファイル: decomposer.py プロジェクト: BQSKit/qfast
    def __init__ ( self, utry, target_gate_size = 2, model = "PermModel",
                   optimizer = "LBFGSOptimizer",
                   hierarchy_fn = lambda x : x // 3 if x > 5 else 2,
                   topology = None, intermediate_solution_callback = None,
                   model_options = {} ):
        """
        Initializes a decomposer.

        Args:
            utry (np.ndarray): A unitary matrix to decompose

            target_gate_size (int): After decomposition, this will be
                the largest size of any gate in the returned list.

            model (str): The circuit model to use during decomposition.

            optimizer (str): The optimizer to use during decomposition.

            hierarchy_fn (callable): This function determines the
                decomposition hierarchy.

            topoology (Topology): Determines the connection of qubits.
                If none, will be set to all-to-all.

            intermediate_solution_callback (None or callable): Callback
                function for intermediate solutions. If not None, then
                a function that takes in a list[Gates] and returns nothing.

        Raises:
            ValueError: If the target_gate_size is nonpositive or too large.

            RuntimeError: If the model or optimizer cannot be found.
        """

        if not utils.is_unitary( utry, tol = 1e-14 ):
            logger.warning( "Unitary is not doubly-precise." )
            logger.warning( "Proceeding with closest unitary to input." )
            self.utry = utils.closest_unitary( utry )
        else:
            self.utry = utry

        self.num_qubits = utils.get_num_qubits( utry )

        if target_gate_size <= 0 or target_gate_size > self.num_qubits:
            raise ValueError( "Invalid target gate size." )

        self.target_gate_size = target_gate_size

        if not callable( hierarchy_fn ):
            raise TypeError( "Invalid hierarchy function." )

        if intermediate_solution_callback is not None:
            if not callable( intermediate_solution_callback ):
                raise TypeError( "Invalid intermediate solution callback." )

        self.hierarchy_fn = hierarchy_fn
        self.intermediate_solution_callback = intermediate_solution_callback

        if topology is not None and not isinstance( topology, Topology ):
            raise TypeError( "Invalid topology." )

        self.topology = topology or Topology( self.num_qubits )

        if model not in plugins.get_models():
            raise RuntimeError( f"Cannot find decomposition model: {model}" )

        self.model = plugins.get_model( model )

        if optimizer not in plugins.get_optimizers():
            raise RuntimeError( f"Cannot find optimizer: {optimizer}" )

        self.model_options = model_options
        self.optimizer = plugins.get_optimizer( optimizer )

        logger.debug( "Created decomposer with %s and %s."
                      % ( model, optimizer ) )
コード例 #10
0
ファイル: test_constructor.py プロジェクト: BQSKit/qfast
 def test_topology_constructor_num_qubits ( self ):
     for n in [ 1, 2, 3, 4 ]:
         t = Topology( n )
         self.assertTrue( t.num_qubits == n )
コード例 #11
0
ファイル: test_constructor.py プロジェクト: BQSKit/qfast
    def test_instantiater_constructor_invalid(self):
        invalid_tool = "test_dummy_tool"
        valid_topology = Topology(3, None)

        self.assertRaises(RuntimeError, Instantiater, invalid_tool,
                          valid_topology)
コード例 #12
0
ファイル: test_constructor.py プロジェクト: BQSKit/qfast
 def test_instantiater_constructor_valid(self):
     valid_tool = "QSearchTool"
     valid_topology = Topology(3, None)
     instantiater = Instantiater(valid_tool, valid_topology)
     self.assertTrue(instantiater.tool.__class__.__name__ == valid_tool)
コード例 #13
0
def synthesize ( utry, model = "PermModel", optimizer = "LBFGSOptimizer",
                 tool = "QSearchTool", combiner = "NaiveCombiner",
                 hierarchy_fn = lambda x : x // 3 if x > 5 else 2,
                 coupling_graph = None, basis_gates = None,
                 intermediate_solution_callback = None, model_options = {} ):
    """
    Synthesize a unitary matrix and return qasm code using QFAST.

    Args:
        utry (np.ndarray): The unitary matrix to synthesize.

        model (str): The model to use during decomposition.

        optimizer (str): The optimizer to use during decomposition.

        tool (str): The native tool to use during instantiation.

        combiner (str): The combiner to use during recombination.

        hierarchy_fn (callable): This function determines the
            decomposition hierarchy.

        coupling_graph (None or list[tuple[int]]): Determines the
            connection of qubits. If none, will be set to all-to-all.

        basis_gates (None or list[str]): Determines the gate set
            for the final circuit. Only works with tools that implement
            this feature.

        intermediate_solution_callback (None or callable): Callback
            function for intermediate solutions. If not None, then
            a function that takes in a list[Gates] and returns nothing.

        model_options (Dict): kwargs for model

    Returns:
        (str): Qasm code implementing utry.

    Raises:
        TypeError: If the coupling_graph is invalid.

        RuntimeError: If the native tool cannot be found.
    """

    if coupling_graph is not None:
        if not utils.is_valid_coupling_graph( coupling_graph ):
            raise TypeError( "The specified coupling graph is invalid." )


    if combiner not in plugins.get_combiners():
        raise RuntimeError( "Cannot find combiner." )

    # Get target_gate_size for decomposition
    if tool not in plugins.get_native_tools():
        raise RuntimeError( "Cannot find native tool." )

    target_gate_size = plugins.get_native_tool( tool )().get_maximum_size()

    num_qubits = utils.get_num_qubits( utry )
    topology = Topology( num_qubits, coupling_graph )

    # Decompose the big input unitary into smaller unitary gates.
    decomposer = Decomposer( utry, target_gate_size = target_gate_size,
                             model = model,
                             optimizer = optimizer,
                             topology = topology,
                             hierarchy_fn = hierarchy_fn,
                             intermediate_solution_callback = intermediate_solution_callback,
                             model_options = model_options )

    gate_list = decomposer.decompose()

    # Instantiate the small unitary gates into native code
    instantiater = Instantiater( tool, topology, basis_gates = basis_gates )
    qasm_list = instantiater.instantiate( gate_list )

    # Recombine all small circuits into one large output
    combiner = plugins.get_combiner( combiner )()
    qasm_out = combiner.combine( qasm_list )

    return qasm_out