Exemplo n.º 1
0
def evaluate_operator_for_parameter_grid(
    ansatz_specs,
    backend_specs,
    grid,
    operator,
    fixed_parameters="None",
):

    ansatz = create_object(json.loads(ansatz_specs))
    backend = create_object(json.loads(backend_specs))

    grid = load_parameter_grid(grid)
    operator = load_qubit_operator(operator)

    if fixed_parameters != "None":
        if type(fixed_parameters) == str:
            if os.path.exists(fixed_parameters):
                fixed_parameters = load_circuit_template_params(fixed_parameters)
    else:
        fixed_parameters = []

    (
        parameter_grid_evaluation,
        optimal_parameters,
    ) = _evaluate_operator_for_parameter_grid(
        ansatz, grid, backend, operator, previous_layer_params=fixed_parameters
    )

    save_parameter_grid_evaluation(
        parameter_grid_evaluation, "parameter-grid-evaluation.json"
    )
    save_circuit_template_params(optimal_parameters, "/app/optimal-parameters.json")
Exemplo n.º 2
0
    def test_unsuccessful_post_result_body_None(self):
        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # POST argument values to allow proxy to verify that argument values that come in with
        # Value POST are correct
        params = np.random.random((2,2))
        save_circuit_template_params(params, 'proxy_test_current_argument_values_artifact.json')
        with open('proxy_test_current_argument_values_artifact.json', 'r') as f:
            arg_val_data = json.load(f)

        # set status to be OPTIMIZING in order to POST argument values
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST argument values
        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(arg_val_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)

        # set status to be EVALUATING
        connection.request('POST', '/status', body="EVALUATING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST cost function result
        connection.request('POST', '/cost-function-results', body=None)
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 400)
        response_lower = response.read().decode("utf-8").lower()
        self.assertTrue(response_lower.find('error') != -1)
        self.assertTrue(response_lower.find('format') != -1)
Exemplo n.º 3
0
    def test_post_current_argument_values(self):
        params = np.random.random((2,2))
        save_circuit_template_params(params, 'proxy_test_current_argument_values_artifact.json')
        with open('proxy_test_current_argument_values_artifact.json', 'r') as f:
            data = json.load(f)

        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # set status to be OPTIMIZING
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)
        # decode id from response
        id_from_argument_value_post = response.read().decode("utf-8")

        connection.request('GET', '/cost-function-argument-values')
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)

        # remove id from response and verify it is correct
        response_json = json.loads(response.read().decode("utf-8"))
        response_id = response_json.pop("optimization-evaluation-id")
        self.assertEqual(id_from_argument_value_post, response_id)

        # assert argument values are same as above
        with open('proxy_test_current_argument_values_artifact_from_proxy.json', 'w') as f:
            f.write(json.dumps(response_json))
        new_data_loaded_from_file = load_circuit_template_params('proxy_test_current_argument_values_artifact_from_proxy.json')
        np.testing.assert_array_equal(params, new_data_loaded_from_file)
Exemplo n.º 4
0
    def __call__(self, parameters) -> ValueEstimate:
        """Evaluates the value of the cost function for given parameters by communicating with client.

        Args:
            parameters (np.ndarray): parameters for which the evaluation should occur

        Returns:
            value: cost function value for given parameters, either int or float.
        """
        # Encode params to json string
        save_circuit_template_params(parameters, "current_optimization_params.json")
        with open("current_optimization_params.json", "r") as f:
            current_params_string = f.read()

        # POST params to proxy
        evaluation_id = self.client.post_argument_values(current_params_string)

        # POST status to EVALUATING
        self.client.post_status("EVALUATING")

        # WAIT for status to be OPTIMIZING
        while self.client.get_status() != "OPTIMIZING":
            time.sleep(1)

        # GET cost function evaluation from proxy
        evaluation_string = self.client.get_evaluation_result(evaluation_id)
        value_estimate = load_value_estimate(io.StringIO(evaluation_string))

        return value_estimate
Exemplo n.º 5
0
    def test_save_parameter_grid_evaluation(self):
        # Given
        ansatz = MockAnsatz(2, 2)
        grid = build_uniform_param_grid(1, 2, 0, np.pi, np.pi / 10)
        backend = create_object({
            "module_name": "zquantum.core.interfaces.mock_objects",
            "function_name": "MockQuantumSimulator",
        })
        op = QubitOperator("0.5 [] + 0.5 [Z1]")
        (
            parameter_grid_evaluation,
            optimal_parameters,
        ) = evaluate_operator_for_parameter_grid(ansatz, grid, backend, op)
        # When
        save_parameter_grid_evaluation(parameter_grid_evaluation,
                                       "parameter-grid-evaluation.json")
        save_circuit_template_params(optimal_parameters,
                                     "optimal-parameters.json")
        # Then
        # TODO

        files_to_remove = ("parameter-grid-evaluation.json",
                           "optimal-parameters.json")
        failed_to_remove = []

        for path in files_to_remove:
            try:
                os.remove(path)
            except OSError:
                failed_to_remove.append(path)

        if failed_to_remove:
            raise RuntimeError(f"Failed to remove files: {failed_to_remove}")
Exemplo n.º 6
0
    def params_filename_and_number_of_layers(self, number_of_layers):
        params = np.random.uniform(low=0, high=np.pi, size=number_of_layers)
        params_filename = "params.json"
        save_circuit_template_params(np.array(params), params_filename)

        yield params_filename, number_of_layers

        remove_file_if_exists(params_filename)
Exemplo n.º 7
0
    def test_post_result(self):
        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # POST argument values to allow proxy to verify that id that comes in with
        # result POST are correct
        params = np.random.random((2,2))
        save_circuit_template_params(params, 'proxy_test_current_argument_values_artifact.json')
        with open('proxy_test_current_argument_values_artifact.json', 'r') as f:
            arg_val_data = json.load(f)

        # set status to be OPTIMIZING in order to POST argument values
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST argument values
        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(arg_val_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)
        # decode id from response
        id_from_argument_value_post = response.read().decode("utf-8")

        # set status to be EVALUATING
        connection.request('POST', '/status', body="EVALUATING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # make cost function result
        result = ValueEstimate(1.5,10.0)
        save_value_estimate(result, 'proxy_test_results_artifact.json')
        with open('proxy_test_results_artifact.json', 'r') as f:
            result_data = json.load(f)
        result_data["optimization-evaluation-id"] = id_from_argument_value_post
        
        # POST cost function result
        connection.request('POST', '/cost-function-results', body=json.JSONEncoder().encode(result_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # GET cost function result
        connection.request('GET', '/cost-function-results', body=id_from_argument_value_post)
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)

        # remove id from response and verify it is correct
        response_string = response.read().decode("utf-8")
        response_json = json.loads(response_string)
        response_id = response_json.pop("optimization-evaluation-id")
        self.assertEqual(id_from_argument_value_post, response_id)

        # assert result is same as above
        with open('proxy_test_results_artifact_from_proxy.json', 'w') as f:
            f.write(json.dumps(response_json))
        new_data_loaded_from_file = load_value_estimate('proxy_test_results_artifact_from_proxy.json')
        self.assertEqual(result.value, new_data_loaded_from_file.value)
        self.assertEqual(result.precision, new_data_loaded_from_file.precision)
Exemplo n.º 8
0
    def params_filenames(self, request):
        params1_filename = "params1.json"
        save_circuit_template_params(np.array(request.param[0]), params1_filename)

        params2_filename = "params2.json"
        save_circuit_template_params(np.array(request.param[1]), params2_filename)

        yield (params1_filename, params2_filename)

        remove_file_if_exists(params1_filename)
        remove_file_if_exists(params2_filename)
Exemplo n.º 9
0
def evaluate_operator_for_parameter_grid(
    ansatz_specs: Specs,
    backend_specs: Specs,
    grid: Union[str, ParameterGrid],
    operator: Union[str, SymbolicOperator],
    fixed_parameters: Union[List[float], np.ndarray, str] = None,
):
    """Measure the expection values of the terms in an input operator with respect to the states prepared by the input
    ansatz circuits when set to the different parameters in the input parameter grid on the
    backend described by the backend_specs. The results are serialized into a JSON under the
    files: "parameter-grid-evaluation.json" and "optimal-parameters.json"

    ARGS:
        ansatz_specs (Union[dict, str]): The ansatz producing the parameterized quantum circuits
        backend_specs (Union[dict, str]): The backend on which to run the quantum circuit
        grid (Union[str, ParameterGrid]): The parameter grid describing the different ansatz parameters to use
        operator (Union[str, SymbolicOperator]): The operator to measure
        fixed_parameters (Union[List[float], np.ndarray, str]): Any fixed parameter values that the ansatz should be
            evaluated to that are not described by the parameter grid
    """
    if isinstance(ansatz_specs, str):
        ansatz_specs = json.loads(ansatz_specs)
    ansatz = create_object(ansatz_specs)

    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    backend = create_object(backend_specs)

    if isinstance(grid, str):
        grid = load_parameter_grid(grid)
    if isinstance(operator, str):
        operator = load_qubit_operator(operator)

    if fixed_parameters is not None:
        if isinstance(fixed_parameters, str):
            fixed_parameters = load_circuit_template_params(fixed_parameters)
    else:
        fixed_parameters = []

    (
        parameter_grid_evaluation,
        optimal_parameters,
    ) = _evaluate_operator_for_parameter_grid(
        ansatz,
        grid,
        backend,
        operator,
        previous_layer_params=fixed_parameters)

    save_parameter_grid_evaluation(parameter_grid_evaluation,
                                   "parameter-grid-evaluation.json")
    save_circuit_template_params(optimal_parameters, "optimal-parameters.json")
Exemplo n.º 10
0
    def test_unsuccessful_post_result_wrong_status(self):
        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # POST argument values to allow proxy to verify that argument values that come in with
        # Value POST are correct
        params = np.random.random((2,2))
        save_circuit_template_params(params, 'proxy_test_current_argument_values_artifact.json')
        with open('proxy_test_current_argument_values_artifact.json', 'r') as f:
            arg_val_data = json.load(f)

        # set status to be OPTIMIZING in order to POST argument values
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST argument values
        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(arg_val_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)
        # decode id from response
        id_from_argument_value_post = response.read().decode("utf-8")

        # set status to be EVALUATING
        connection.request('POST', '/status', body="EVALUATING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # make cost function result
        result = ValueEstimate(1.5,10.0)
        save_value_estimate(result, 'proxy_test_results_artifact.json')
        with open('proxy_test_results_artifact.json', 'r') as f:
            result_data = json.load(f)
        result_data["optimization-evaluation-id"] = id_from_argument_value_post
        
        # set status to be OPTIMIZING - new results should not be able to
        # be posted while that is the status
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST cost function result
        connection.request('POST', '/cost-function-results', body=json.JSONEncoder().encode(result_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 409)
        response_lower = response.read().decode("utf-8").lower()
        self.assertTrue(response_lower.find('error') != -1)
        self.assertTrue(response_lower.find('status') != -1)
        self.assertTrue(response_lower.find('evaluating') != -1)
Exemplo n.º 11
0
def generate_random_ansatz_params(
    ansatz_specs: Dict,
    number_of_parameters: Union[str, int] = "None",
    min_value: float = -np.pi * 0.5,
    max_value: float = np.pi * 0.5,
    seed: Union[str, int] = "None",
):
    if ansatz_specs != "None":  # TODO None issue in workflow v1
        ansatz_specs_dict = json.loads(ansatz_specs)
        ansatz = create_object(ansatz_specs_dict)
        number_of_params = ansatz.number_of_params
    elif number_of_parameters != "None":
        number_of_params = number_of_parameters
    if seed != "None":
        np.random.seed(seed)
    params = np.random.uniform(min_value, max_value, number_of_params)
    save_circuit_template_params(params, "params.json")
Exemplo n.º 12
0
 def test_save_parameter_grid_evaluation(self):
     # Given
     ansatz = MockAnsatz(2, 2)
     grid = build_uniform_param_grid(1, 2, 0, np.pi, np.pi / 10)
     backend = create_object({
         "module_name": "zquantum.core.interfaces.mock_objects",
         "function_name": "MockQuantumSimulator",
     })
     op = QubitOperator("0.5 [] + 0.5 [Z1]")
     (
         parameter_grid_evaluation,
         optimal_parameters,
     ) = evaluate_operator_for_parameter_grid(ansatz, grid, backend, op)
     # When
     save_parameter_grid_evaluation(parameter_grid_evaluation,
                                    "parameter-grid-evaluation.json")
     save_circuit_template_params(optimal_parameters,
                                  "optimal-parameters.json")
Exemplo n.º 13
0
    def test_build_ansatz_circuit_raises_exception_on_invalid_inputs(self):
        params_filename = "params.json"
        save_circuit_template_params(np.array([1.0]), params_filename)

        ansatz_specs = {
            "module_name": "zquantum.core.interfaces.mock_objects",
            "function_name": "MockAnsatz",
            "number_of_layers": 0,
            "problem_size": 2,
        }

        try:
            circuit_filename = "circuit.json"
            with pytest.raises(Exception):
                build_ansatz_circuit(ansatz_specs=ansatz_specs, params=params_filename)
        finally:
            remove_file_if_exists(params_filename)
            remove_file_if_exists(circuit_filename)
Exemplo n.º 14
0
def generate_random_ansatz_params(
    ansatz_specs: Optional[Specs] = None,
    number_of_parameters: Optional[int] = None,
    min_value: float = -np.pi * 0.5,
    max_value: float = np.pi * 0.5,
    seed: Optional[int] = None,
):
    assert (ansatz_specs is None) != (number_of_parameters is None)

    if ansatz_specs is not None:
        ansatz = load_from_specs(ansatz_specs)
        number_of_parameters = ansatz.number_of_params

    if seed is not None:
        np.random.seed(seed)

    params = np.random.uniform(min_value, max_value, number_of_parameters)
    save_circuit_template_params(params, "params.json")
Exemplo n.º 15
0
    def _evaluate(self, parameters):
        """
        Evaluates the value of the cost function for given parameters by communicating with client.

        Args:
            parameters (np.ndarray): parameters for which the evaluation should occur

        Returns:
            value: cost function value for given parameters, either int or float.
        """
        # Encode params to json string
        save_circuit_template_params(parameters,
                                     'current_optimization_params.json')
        with open('current_optimization_params.json', 'r') as f:
            current_params_string = f.read()

        # POST params to proxy
        evaluation_id = self.client.post_argument_values(current_params_string)

        # POST status to EVALUATING
        self.client.post_status("EVALUATING")

        # WAIT for status to be OPTIMIZING
        while self.client.get_status() != "OPTIMIZING":
            time.sleep(1)

        # GET cost function evaluation from proxy
        evaluation_string = self.client.get_evaluation_result(evaluation_id)
        value_estimate = load_value_estimate(io.StringIO(evaluation_string))

        # SAVE ID to optimization result['history']
        if self.save_evaluation_history:
            if len(self.evaluations_history) < self.current_iteration + 1:
                self.evaluations_history.append(
                    {'optimization-evaluation-ids': []})
            self.evaluations_history[self.current_iteration][
                'optimization-evaluation-ids'].append(evaluation_id)
            self.evaluations_history[
                self.current_iteration]["params"] = parameters
            self.evaluations_history[
                self.current_iteration]["value"] = value_estimate.value

        return value_estimate.value
Exemplo n.º 16
0
def optimize_variational_qcbm_circuit(
    distance_measure_specs,
    distance_measure_parameters,
    n_layers,
    n_qubits,
    topology,
    backend_specs,
    optimizer_specs,
    initial_parameters,
    target_distribution,
):

    if isinstance(distance_measure_specs, str):
        distance_measure_specs = json.loads(distance_measure_specs)
    distance_measure = get_func_from_specs(distance_measure_specs)

    ansatz = QCBMAnsatz(n_layers, n_qubits, topology)

    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    backend = create_object(backend_specs)

    if isinstance(optimizer_specs, str):
        optimizer_specs = json.loads(optimizer_specs)
    optimizer = create_object(optimizer_specs)

    initial_parameters = load_circuit_template_params(initial_parameters)
    target_distribution = load_bitstring_distribution(target_distribution)

    if isinstance(distance_measure_parameters, str):
        distance_measure_parameters = json.loads(distance_measure_parameters)

    cost_function = QCBMCostFunction(
        ansatz,
        backend,
        distance_measure,
        distance_measure_parameters,
        target_distribution,
    )
    opt_results = optimizer.minimize(cost_function, initial_parameters)
    save_optimization_results(opt_results, "qcbm-optimization-results.json")
    save_circuit_template_params(opt_results.opt_params,
                                 "optimized-parameters.json")
Exemplo n.º 17
0
    def test_unsuccessful_post_current_argument_values_wrong_status(self):
        params = np.random.random((2,2))
        save_circuit_template_params(params, 'proxy_test_current_argument_values_artifact.json')
        with open('proxy_test_current_argument_values_artifact.json', 'r') as f:
            data = json.load(f)

        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # set status to be EVALUATING - new argument values should not be able to
        # be posted while that is the status
        connection.request('POST', '/status', body="EVALUATING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 409)
        response_lower = response.read().decode("utf-8").lower()
        self.assertTrue(response_lower.find('error') != -1)
        self.assertTrue(response_lower.find('status') != -1)
Exemplo n.º 18
0
def combine_ansatz_params(params1: str, params2: str):
    parameters1 = load_circuit_template_params(params1)
    parameters2 = load_circuit_template_params(params2)
    combined_params = _combine_ansatz_params(parameters1, parameters2)
    save_circuit_template_params(combined_params, "combined-params.json")
Exemplo n.º 19
0
def extract_xfav_params_from_cma_es_opt_results(optimization_results):
    opt_results = load_optimization_results(optimization_results)
    save_circuit_template_params(np.array(opt_results.cma_xfavorite),
                                 "fav-params.json")
Exemplo n.º 20
0
def optimize_variational_circuit(
    ansatz_specs,
    backend_specs,
    optimizer_specs,
    cost_function_specs,
    qubit_operator,
    initial_parameters="None",
    fixed_parameters="None",
    noise_model="None",
    device_connectivity="None",
    parameter_grid="None",
    constraint_operator="None",
):
    if initial_parameters != "None":
        initial_params = load_circuit_template_params(initial_parameters)
    else:
        initial_params = None

    if fixed_parameters != "None":
        fixed_params = load_circuit_template_params(fixed_parameters)
    else:
        fixed_params = None

    # Load qubit operator
    operator = load_qubit_operator(qubit_operator)

    if isinstance(ansatz_specs, str):
        ansatz_specs_dict = yaml.load(ansatz_specs, Loader=yaml.SafeLoader)
    else:
        ansatz_specs_dict = ansatz_specs
    if ansatz_specs_dict["function_name"] == "QAOAFarhiAnsatz":
        ansatz = create_object(ansatz_specs_dict, cost_hamiltonian=operator)
    else:
        ansatz = create_object(ansatz_specs_dict)

    # Load parameter grid
    if parameter_grid != "None":
        grid = load_parameter_grid(parameter_grid)
    else:
        grid = None

    # Load optimizer specs
    if isinstance(optimizer_specs, str):
        optimizer_specs_dict = yaml.load(optimizer_specs,
                                         Loader=yaml.SafeLoader)
    else:
        optimizer_specs_dict = optimizer_specs
    if (grid is not None and optimizer_specs_dict["function_name"]
            == "GridSearchOptimizer"):
        optimizer = create_object(optimizer_specs_dict, grid=grid)
    else:
        optimizer = create_object(optimizer_specs_dict)

    # Load backend specs
    if isinstance(backend_specs, str):
        backend_specs_dict = yaml.load(backend_specs, Loader=yaml.SafeLoader)
    else:
        backend_specs_dict = backend_specs
    if noise_model != "None":
        backend_specs_dict["noise_model"] = load_noise_model(noise_model)
    if device_connectivity != "None":
        backend_specs_dict["device_connectivity"] = load_circuit_connectivity(
            device_connectivity)
    backend = create_object(backend_specs_dict)

    # Load cost function specs
    if isinstance(cost_function_specs, str):
        cost_function_specs_dict = yaml.load(cost_function_specs,
                                             Loader=yaml.SafeLoader)
    else:
        cost_function_specs_dict = cost_function_specs
    estimator_specs = cost_function_specs_dict.pop("estimator-specs", None)
    if estimator_specs is not None:
        cost_function_specs_dict["estimator"] = create_object(estimator_specs)
    cost_function_specs_dict["target_operator"] = operator
    cost_function_specs_dict["ansatz"] = ansatz
    cost_function_specs_dict["backend"] = backend
    cost_function_specs_dict["fixed_parameters"] = fixed_params
    cost_function = create_object(cost_function_specs_dict)

    if constraint_operator != "None":
        constraint_op = load_qubit_operator(constraint_operator)
        constraints_cost_function_specs = yaml.load(cost_function_specs,
                                                    Loader=yaml.SafeLoader)
        constraints_estimator_specs = constraints_cost_function_specs.pop(
            "estimator-specs", None)
        if constraints_estimator_specs is not None:
            constraints_cost_function_specs["estimator"] = create_object(
                constraints_estimator_specs)
        constraints_cost_function_specs["ansatz"] = ansatz
        constraints_cost_function_specs["backend"] = backend
        constraints_cost_function_specs["target_operator"] = constraint_op
        constraint_cost_function = create_object(
            constraints_cost_function_specs)
        constraint_cost_function_wrapper = (
            lambda params: constraint_cost_function.evaluate(params).value)
        constraint_functions = ({
            "type": "eq",
            "fun": constraint_cost_function_wrapper
        }, )
        optimizer.constraints = constraint_functions

    opt_results = optimizer.minimize(cost_function, initial_params)

    save_optimization_results(opt_results, "optimization-results.json")
    save_circuit_template_params(opt_results.opt_params,
                                 "optimized-parameters.json")