classiq 0.37.1__py3-none-any.whl → 0.65.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +49 -34
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +241 -95
- classiq/_internals/async_utils.py +2 -77
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +18 -8
- classiq/_internals/authentication/password_manager.py +40 -13
- classiq/_internals/authentication/token_manager.py +11 -6
- classiq/_internals/client.py +106 -37
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +56 -50
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +50 -47
- classiq/analyzer/analyzer_utilities.py +15 -15
- classiq/analyzer/rb.py +19 -20
- classiq/analyzer/show_interactive_hack.py +30 -7
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/__init__.py +3 -12
- classiq/applications/chemistry/__init__.py +14 -10
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
- classiq/applications/combinatorial_helpers/memory.py +75 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
- classiq/applications/combinatorial_optimization/__init__.py +24 -5
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +4 -5
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
- classiq/applications/grover/__init__.py +9 -0
- classiq/applications/grover/grover_model_constructor.py +157 -0
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +8 -8
- classiq/applications/qnn/datasets/__init__.py +9 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +30 -10
- classiq/applications/qnn/torch_utils.py +4 -3
- classiq/applications/qnn/types.py +7 -7
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +4 -10
- classiq/applications/qsvm/qsvm_data_generation.py +5 -8
- classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
- classiq/execution/__init__.py +8 -3
- classiq/execution/all_hardware_devices.py +11 -0
- classiq/execution/execution_session.py +400 -0
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +197 -25
- classiq/execution/qnn.py +79 -0
- classiq/executor.py +23 -117
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +49 -16
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +36 -32
- classiq/interface/applications/qsvm.py +28 -25
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -119
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +27 -22
- classiq/interface/backend/quantum_backend_providers.py +70 -16
- classiq/interface/chemistry/fermionic_operator.py +43 -32
- classiq/interface/chemistry/ground_state_problem.py +42 -24
- classiq/interface/chemistry/molecule.py +20 -14
- classiq/interface/chemistry/operator.py +75 -236
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +86 -0
- classiq/interface/exceptions.py +201 -0
- classiq/interface/execution/iqcc.py +19 -0
- classiq/interface/execution/jobs.py +15 -12
- classiq/interface/execution/primitives.py +18 -0
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +26 -143
- classiq/interface/executor/execution_request.py +36 -56
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +34 -22
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
- classiq/interface/executor/quantum_instruction_set.py +3 -2
- classiq/interface/executor/register_initialization.py +12 -17
- classiq/interface/executor/result.py +122 -64
- classiq/interface/executor/vqe_result.py +11 -11
- classiq/interface/finance/function_input.py +42 -19
- classiq/interface/finance/gaussian_model_input.py +7 -5
- classiq/interface/finance/log_normal_model_input.py +6 -4
- classiq/interface/finance/model_input.py +6 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +27 -14
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
- classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +48 -69
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
- classiq/interface/generator/arith/argument_utils.py +57 -6
- classiq/interface/generator/arith/arithmetic.py +37 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
- classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
- classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
- classiq/interface/generator/arith/arithmetic_operations.py +19 -16
- classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
- classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
- classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
- classiq/interface/generator/arith/binary_ops.py +375 -139
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -23
- classiq/interface/generator/arith/logical_ops.py +16 -12
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +44 -48
- classiq/interface/generator/arith/register_user_input.py +70 -27
- classiq/interface/generator/arith/unary_ops.py +57 -46
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/builtin_api_builder.py +2 -9
- classiq/interface/generator/chemistry_function_params.py +5 -5
- classiq/interface/generator/circuit_code/circuit_code.py +7 -7
- classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
- classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
- classiq/interface/generator/compiler_keywords.py +8 -0
- classiq/interface/generator/complex_type.py +13 -25
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +35 -28
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/custom_ansatz.py +2 -5
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
- classiq/interface/generator/expressions/enums/__init__.py +0 -10
- classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
- classiq/interface/generator/expressions/evaluated_expression.py +21 -7
- classiq/interface/generator/expressions/expression.py +27 -15
- classiq/interface/generator/expressions/expression_constants.py +9 -3
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
- classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
- classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
- classiq/interface/generator/finance.py +3 -3
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
- classiq/interface/generator/function_params.py +42 -69
- classiq/interface/generator/functions/__init__.py +0 -22
- classiq/interface/generator/functions/builtins/__init__.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
- classiq/interface/generator/functions/classical_function_declaration.py +18 -9
- classiq/interface/generator/functions/classical_type.py +47 -166
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +13 -14
- classiq/interface/generator/functions/port_declaration.py +1 -13
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +90 -0
- classiq/interface/generator/generated_circuit_data.py +155 -22
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -23
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
- classiq/interface/generator/hardware/hardware_data.py +76 -36
- classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
- classiq/interface/generator/hartree_fock.py +14 -4
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +33 -19
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +20 -16
- classiq/interface/generator/mcx.py +29 -20
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +27 -8
- classiq/interface/generator/model/model.py +32 -203
- classiq/interface/generator/model/preferences/preferences.py +118 -43
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +17 -13
- classiq/interface/generator/oracles/oracle_abc.py +9 -9
- classiq/interface/generator/partitioned_register.py +7 -7
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +47 -34
- classiq/interface/generator/qsvm.py +13 -17
- classiq/interface/generator/quantum_function_call.py +107 -87
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
- classiq/interface/generator/range_types.py +13 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +11 -6
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +16 -15
- classiq/interface/generator/state_preparation/metrics.py +5 -7
- classiq/interface/generator/state_preparation/state_preparation.py +30 -23
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
- classiq/interface/generator/transpiler_basis_gates.py +7 -3
- classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
- classiq/interface/generator/types/compilation_metadata.py +6 -0
- classiq/interface/generator/types/enum_declaration.py +54 -0
- classiq/interface/generator/types/qstruct_declaration.py +18 -0
- classiq/interface/generator/types/struct_declaration.py +15 -14
- classiq/interface/generator/ucc.py +9 -6
- classiq/interface/generator/unitary_gate.py +10 -6
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +11 -9
- classiq/interface/generator/validations/validator_functions.py +8 -6
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +31 -10
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/custom_pydantic_types.py +40 -50
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +7 -11
- classiq/interface/helpers/validation_helpers.py +4 -21
- classiq/interface/helpers/versioned_model.py +1 -1
- classiq/interface/ide/ide_data.py +16 -20
- classiq/interface/ide/visual_model.py +130 -0
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +35 -6
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +44 -14
- classiq/interface/model/classical_if.py +15 -0
- classiq/interface/model/classical_parameter_declaration.py +33 -3
- classiq/interface/model/control.py +45 -0
- classiq/interface/model/handle_binding.py +298 -20
- classiq/interface/model/inplace_binary_operation.py +31 -26
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +87 -73
- classiq/interface/model/native_function_definition.py +16 -21
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +27 -9
- classiq/interface/model/power.py +14 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
- classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
- classiq/interface/model/quantum_function_call.py +146 -462
- classiq/interface/model/quantum_function_declaration.py +193 -152
- classiq/interface/model/quantum_lambda_function.py +65 -0
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +205 -67
- classiq/interface/model/quantum_variable_declaration.py +4 -26
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +58 -0
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +13 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +22 -21
- classiq/interface/source_reference.py +59 -0
- classiq/model_expansions/__init__.py +0 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
- classiq/model_expansions/capturing/__init__.py +0 -0
- classiq/model_expansions/capturing/captured_vars.py +435 -0
- classiq/model_expansions/capturing/mangling_utils.py +56 -0
- classiq/model_expansions/closure.py +171 -0
- classiq/model_expansions/debug_flag.py +3 -0
- classiq/model_expansions/evaluators/__init__.py +0 -0
- classiq/model_expansions/evaluators/arg_type_match.py +158 -0
- classiq/model_expansions/evaluators/argument_types.py +42 -0
- classiq/model_expansions/evaluators/classical_expression.py +36 -0
- classiq/model_expansions/evaluators/control.py +144 -0
- classiq/model_expansions/evaluators/parameter_types.py +226 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
- classiq/model_expansions/evaluators/type_type_match.py +90 -0
- classiq/model_expansions/expression_evaluator.py +135 -0
- classiq/model_expansions/expression_renamer.py +76 -0
- classiq/model_expansions/function_builder.py +247 -0
- classiq/model_expansions/generative_functions.py +158 -0
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +18 -0
- classiq/model_expansions/quantum_operations/__init__.py +9 -0
- classiq/model_expansions/quantum_operations/bind.py +60 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
- classiq/model_expansions/quantum_operations/classicalif.py +53 -0
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +181 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
- classiq/model_expansions/quantum_operations/repeat.py +56 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
- classiq/model_expansions/scope.py +240 -0
- classiq/model_expansions/scope_initialization.py +150 -0
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
- classiq/model_expansions/transformers/__init__.py +0 -0
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +299 -0
- classiq/model_expansions/utils/__init__.py +0 -0
- classiq/model_expansions/utils/counted_name_allocator.py +11 -0
- classiq/model_expansions/utils/handles_collector.py +33 -0
- classiq/model_expansions/visitors/__init__.py +0 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
- classiq/model_expansions/visitors/variable_references.py +144 -0
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/open_library/functions/amplitude_estimation.py +30 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
- classiq/open_library/functions/grover.py +157 -0
- classiq/open_library/functions/hea.py +115 -0
- classiq/open_library/functions/linear_pauli_rotation.py +82 -0
- classiq/open_library/functions/modular_exponentiation.py +201 -0
- classiq/open_library/functions/qaoa_penalty.py +117 -0
- classiq/open_library/functions/qft_functions.py +54 -0
- classiq/open_library/functions/qpe.py +46 -0
- classiq/open_library/functions/qsvt.py +331 -0
- classiq/open_library/functions/state_preparation.py +301 -0
- classiq/open_library/functions/swap_test.py +27 -0
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/open_library/functions/variational.py +52 -0
- classiq/qmod/__init__.py +17 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +60 -47
- classiq/qmod/builtins/classical_functions.py +44 -38
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/enums.py +208 -0
- classiq/qmod/builtins/functions/__init__.py +137 -0
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +55 -0
- classiq/qmod/builtins/functions/benchmarking.py +8 -0
- classiq/qmod/builtins/functions/chemistry.py +91 -0
- classiq/qmod/builtins/functions/exponentiation.py +105 -0
- classiq/qmod/builtins/functions/finance.py +34 -0
- classiq/qmod/builtins/functions/operators.py +16 -0
- classiq/qmod/builtins/functions/qsvm.py +24 -0
- classiq/qmod/builtins/functions/standard_gates.py +651 -0
- classiq/qmod/builtins/operations.py +379 -57
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +8 -20
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +145 -112
- classiq/qmod/expression_query.py +39 -0
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +19 -5
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +194 -0
- classiq/qmod/native/pretty_printer.py +401 -0
- classiq/qmod/pretty_print/__init__.py +7 -0
- classiq/qmod/pretty_print/expression_to_python.py +222 -0
- classiq/qmod/pretty_print/pretty_printer.py +572 -0
- classiq/qmod/python_classical_type.py +67 -0
- classiq/qmod/qfunc.py +79 -0
- classiq/qmod/qmod_constant.py +143 -0
- classiq/qmod/qmod_parameter.py +84 -53
- classiq/qmod/qmod_variable.py +497 -100
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +278 -105
- classiq/qmod/quantum_function.py +232 -48
- classiq/qmod/semantics/__init__.py +0 -0
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
- classiq/qmod/semantics/error_manager.py +88 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +384 -0
- classiq/qmod/semantics/validation/__init__.py +0 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- classiq/qmod/semantics/validation/func_call_validation.py +99 -0
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +128 -0
- classiq/qmod/symbolic.py +178 -111
- classiq/qmod/symbolic_expr.py +36 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +108 -1
- classiq/qmod/write_qmod.py +53 -0
- classiq/synthesis.py +210 -22
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
- classiq-0.65.3.dist-info/RECORD +521 -0
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/grover_model_constructor.py +0 -227
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/exceptions.py +0 -131
- classiq/interface/executor/aws_execution_cost.py +0 -72
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- classiq/interface/generator/functions/foreign_function_definition.py +0 -106
- classiq/interface/generator/functions/function_implementation.py +0 -103
- classiq/interface/generator/functions/native_function_definition.py +0 -153
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -42
- classiq/interface/generator/functions/register_mapping_data.py +0 -102
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -63
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -95
- classiq/interface/model/resolvers/function_call_resolver.py +0 -43
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -154
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/qmod/builtins/functions.py +0 -896
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- classiq-0.37.1.dist-info/RECORD +0 -418
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
- /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
@@ -1,21 +1,21 @@
|
|
1
|
-
from typing import Any
|
1
|
+
from typing import Any
|
2
2
|
|
3
3
|
from classiq.interface.applications.qsvm import DataList, LabelsInt
|
4
|
-
from classiq.interface.
|
5
|
-
from classiq.interface.generator.expressions.enums.qsvm_feature_map_entanglement import (
|
6
|
-
QSVMFeatureMapEntanglement,
|
7
|
-
)
|
4
|
+
from classiq.interface.exceptions import ClassiqValueError
|
8
5
|
from classiq.interface.generator.expressions.expression import Expression
|
9
6
|
from classiq.interface.generator.functions.port_declaration import (
|
10
7
|
PortDeclarationDirection,
|
11
8
|
)
|
9
|
+
from classiq.interface.model.allocate import Allocate
|
12
10
|
from classiq.interface.model.handle_binding import HandleBinding
|
13
11
|
from classiq.interface.model.model import Model, SerializedModel
|
14
12
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
15
13
|
from classiq.interface.model.port_declaration import PortDeclaration
|
16
14
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
15
|
+
from classiq.interface.model.quantum_statement import QuantumStatement
|
17
16
|
|
18
|
-
from classiq.
|
17
|
+
from classiq.qmod.builtins.enums import Pauli, QSVMFeatureMapEntanglement
|
18
|
+
from classiq.qmod.utilities import qmod_val_to_expr_str
|
19
19
|
|
20
20
|
INVALID_FEATURE_MAP_FUNC_NAME_MSG = "Invalid feature_map_function_name, it can be bloch_sphere_feature_map or pauli_feature_map"
|
21
21
|
|
@@ -24,43 +24,46 @@ _OUTPUT_VARIABLE_NAME = "qsvm_results"
|
|
24
24
|
|
25
25
|
def _bloch_sphere_feature_map_function_params(
|
26
26
|
bloch_feature_dimension: int,
|
27
|
-
) ->
|
28
|
-
return
|
29
|
-
|
30
|
-
|
27
|
+
) -> tuple[list[Expression], str]:
|
28
|
+
return [
|
29
|
+
Expression(expr=f"{bloch_feature_dimension}")
|
30
|
+
], f"ceiling({bloch_feature_dimension}/2)"
|
31
31
|
|
32
32
|
|
33
33
|
def _pauli_feature_map_function_params(
|
34
|
-
paulis:
|
34
|
+
paulis: list[list[Pauli]],
|
35
35
|
entanglement: QSVMFeatureMapEntanglement,
|
36
36
|
alpha: int,
|
37
37
|
reps: int,
|
38
38
|
feature_dimension: int,
|
39
|
-
) ->
|
39
|
+
) -> tuple[list[Expression], str]:
|
40
40
|
paulis_str = (
|
41
41
|
"["
|
42
42
|
+ ",".join(
|
43
|
-
[
|
43
|
+
[
|
44
|
+
"[" + ",".join([qmod_val_to_expr_str(p) for p in p_list]) + "]"
|
45
|
+
for p_list in paulis
|
46
|
+
]
|
44
47
|
)
|
45
48
|
+ "]"
|
46
49
|
)
|
47
50
|
pauli_feature_map_params = (
|
48
51
|
f"paulis={paulis_str}, "
|
49
|
-
f"entanglement={entanglement}, "
|
52
|
+
f"entanglement={qmod_val_to_expr_str(entanglement)}, "
|
50
53
|
f"alpha={alpha}, "
|
51
54
|
f"reps={reps}, "
|
52
55
|
f"feature_dimension={feature_dimension}"
|
53
56
|
)
|
54
|
-
return
|
55
|
-
|
57
|
+
return [
|
58
|
+
Expression(
|
56
59
|
expr=f"struct_literal(QSVMFeatureMapPauli, {pauli_feature_map_params})"
|
57
60
|
)
|
58
|
-
|
61
|
+
], f"{feature_dimension}"
|
59
62
|
|
60
63
|
|
61
64
|
def get_qsvm_qmain_body(
|
62
65
|
feature_map_function_name: str, **kwargs: Any
|
63
|
-
) ->
|
66
|
+
) -> list[QuantumStatement]:
|
64
67
|
if feature_map_function_name == "bloch_sphere_feature_map":
|
65
68
|
params, size_expr = _bloch_sphere_feature_map_function_params(**kwargs)
|
66
69
|
elif feature_map_function_name == "pauli_feature_map":
|
@@ -69,14 +72,13 @@ def get_qsvm_qmain_body(
|
|
69
72
|
raise ClassiqValueError(INVALID_FEATURE_MAP_FUNC_NAME_MSG)
|
70
73
|
|
71
74
|
return [
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
+
Allocate(
|
76
|
+
size=Expression(expr=size_expr),
|
77
|
+
target=HandleBinding(name="qbv"),
|
75
78
|
),
|
76
79
|
QuantumFunctionCall(
|
77
80
|
function=feature_map_function_name,
|
78
|
-
|
79
|
-
inouts={"qbv": HandleBinding(name="qbv")},
|
81
|
+
positional_args=[*params, HandleBinding(name="qbv")],
|
80
82
|
),
|
81
83
|
]
|
82
84
|
|
@@ -94,12 +96,12 @@ def construct_qsvm_model(
|
|
94
96
|
functions=[
|
95
97
|
NativeFunctionDefinition(
|
96
98
|
name="main",
|
97
|
-
|
98
|
-
|
99
|
+
positional_arg_declarations=[
|
100
|
+
PortDeclaration(
|
99
101
|
name="qbv",
|
100
102
|
direction=PortDeclarationDirection.Output,
|
101
|
-
)
|
102
|
-
|
103
|
+
),
|
104
|
+
],
|
103
105
|
body=get_qsvm_qmain_body(
|
104
106
|
feature_map_function_name=feature_map_function_name, **kwargs
|
105
107
|
),
|
@@ -114,7 +116,7 @@ def construct_qsvm_model(
|
|
114
116
|
predict_data={predict_data}
|
115
117
|
)
|
116
118
|
save({{{_OUTPUT_VARIABLE_NAME!r}: {_OUTPUT_VARIABLE_NAME}}})
|
117
|
-
""",
|
119
|
+
""".strip(),
|
118
120
|
)
|
119
121
|
|
120
122
|
return qsvm_qmod.get_model()
|
classiq/execution/__init__.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
1
|
from ..executor import * # noqa: F403
|
4
2
|
from ..executor import __all__ as _exec_all
|
5
3
|
from ..interface.backend.backend_preferences import * # noqa: F403
|
@@ -9,7 +7,10 @@ from ..interface.executor.execution_preferences import __all__ as _ep_all
|
|
9
7
|
from ..interface.executor.iqae_result import IQAEResult
|
10
8
|
from ..interface.executor.result import ExecutionDetails
|
11
9
|
from ..interface.executor.vqe_result import VQESolverResult
|
10
|
+
from .execution_session import ExecutionSession
|
11
|
+
from .iqcc import generate_iqcc_token, generate_iqcc_token_async
|
12
12
|
from .jobs import ExecutionJob, get_execution_jobs, get_execution_jobs_async
|
13
|
+
from .qnn import execute_qnn
|
13
14
|
|
14
15
|
__all__ = (
|
15
16
|
_be_all
|
@@ -22,9 +23,13 @@ __all__ = (
|
|
22
23
|
"ExecutionJob",
|
23
24
|
"get_execution_jobs",
|
24
25
|
"get_execution_jobs_async",
|
26
|
+
"ExecutionSession",
|
27
|
+
"execute_qnn",
|
28
|
+
"generate_iqcc_token",
|
29
|
+
"generate_iqcc_token_async",
|
25
30
|
]
|
26
31
|
)
|
27
32
|
|
28
33
|
|
29
|
-
def __dir__() ->
|
34
|
+
def __dir__() -> list[str]:
|
30
35
|
return __all__
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from classiq.interface.hardware import HardwareInformation
|
2
|
+
|
3
|
+
from classiq._internals import async_utils
|
4
|
+
from classiq._internals.api_wrapper import ApiWrapper
|
5
|
+
|
6
|
+
|
7
|
+
def get_all_hardware_devices() -> list[HardwareInformation]:
|
8
|
+
"""
|
9
|
+
Returns a list of all hardware devices known to Classiq.
|
10
|
+
"""
|
11
|
+
return async_utils.run(ApiWrapper.call_get_all_hardware_devices())
|
@@ -0,0 +1,400 @@
|
|
1
|
+
import json
|
2
|
+
import random
|
3
|
+
from types import TracebackType
|
4
|
+
from typing import Callable, Optional, Union, cast
|
5
|
+
|
6
|
+
import numpy as np
|
7
|
+
|
8
|
+
from classiq.interface.chemistry.operator import PauliOperator, pauli_integers_to_str
|
9
|
+
from classiq.interface.exceptions import ClassiqError, ClassiqValueError
|
10
|
+
from classiq.interface.execution.primitives import EstimateInput, PrimitivesInput
|
11
|
+
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
12
|
+
from classiq.interface.executor.result import (
|
13
|
+
EstimationResult,
|
14
|
+
ExecutionDetails,
|
15
|
+
ParsedState,
|
16
|
+
)
|
17
|
+
from classiq.interface.generator.arith import number_utils
|
18
|
+
from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
|
19
|
+
from classiq.interface.generator.quantum_program import QuantumProgram
|
20
|
+
from classiq.interface.model.quantum_type import QuantumBit, QuantumNumeric
|
21
|
+
|
22
|
+
from classiq._internals import async_utils
|
23
|
+
from classiq._internals.api_wrapper import ApiWrapper
|
24
|
+
from classiq._internals.client import client
|
25
|
+
from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
|
26
|
+
_pauli_dict_to_pauli_terms,
|
27
|
+
)
|
28
|
+
from classiq.execution.jobs import ExecutionJob
|
29
|
+
from classiq.qmod.builtins import PauliTerm
|
30
|
+
from classiq.qmod.builtins.classical_execution_primitives import (
|
31
|
+
CARRAY_SEPARATOR,
|
32
|
+
ExecutionParams,
|
33
|
+
)
|
34
|
+
from classiq.synthesis import SerializedQuantumProgram
|
35
|
+
|
36
|
+
Hamiltonian = Union[list[QmodPyStruct], list[PauliTerm]]
|
37
|
+
Program = Union[SerializedQuantumProgram, QuantumProgram]
|
38
|
+
ParsedExecutionParams = dict[str, Union[float, int]]
|
39
|
+
ExecutionParameters = Optional[Union[ExecutionParams, list[ExecutionParams]]]
|
40
|
+
ParsedExecutionParameters = Optional[
|
41
|
+
Union[ParsedExecutionParams, list[ParsedExecutionParams]]
|
42
|
+
]
|
43
|
+
|
44
|
+
|
45
|
+
def _deserialize_program(program: Program) -> QuantumProgram:
|
46
|
+
return (
|
47
|
+
program
|
48
|
+
if isinstance(program, QuantumProgram)
|
49
|
+
else QuantumProgram.model_validate(json.loads(program))
|
50
|
+
)
|
51
|
+
|
52
|
+
|
53
|
+
def hamiltonian_to_pauli_terms(hamiltonian: Hamiltonian) -> list[PauliTerm]:
|
54
|
+
if isinstance(hamiltonian[0], PauliTerm):
|
55
|
+
return cast(list[PauliTerm], hamiltonian)
|
56
|
+
else:
|
57
|
+
return _pauli_dict_to_pauli_terms(cast(list[QmodPyStruct], hamiltonian))
|
58
|
+
|
59
|
+
|
60
|
+
def _hamiltonian_to_pauli_operator(hamiltonian: Hamiltonian) -> PauliOperator:
|
61
|
+
pauli_list = [
|
62
|
+
(
|
63
|
+
pauli_integers_to_str(elem.pauli), # type: ignore[arg-type]
|
64
|
+
elem.coefficient,
|
65
|
+
)
|
66
|
+
for elem in hamiltonian_to_pauli_terms(hamiltonian)
|
67
|
+
]
|
68
|
+
return PauliOperator(pauli_list=pauli_list)
|
69
|
+
|
70
|
+
|
71
|
+
def parse_params(params: ExecutionParams) -> ParsedExecutionParams:
|
72
|
+
result = {}
|
73
|
+
for key, values in params.items():
|
74
|
+
if isinstance(values, list):
|
75
|
+
for index, value in enumerate(values):
|
76
|
+
new_key = f"{key}{CARRAY_SEPARATOR}{index}"
|
77
|
+
result[new_key] = value
|
78
|
+
elif isinstance(values, (int, float)):
|
79
|
+
result[key] = values
|
80
|
+
else:
|
81
|
+
raise TypeError("Parameters were provided in un-supported format")
|
82
|
+
return result
|
83
|
+
|
84
|
+
|
85
|
+
class ExecutionSession:
|
86
|
+
"""
|
87
|
+
A session for executing a quantum program.
|
88
|
+
`ExecutionSession` allows to execute the quantum program with different parameters and operations without the need to re-synthesize the model.
|
89
|
+
The session must be closed in order to ensure resources are properly cleaned up. It's recommended to use `ExecutionSession` as a context manager for this purpose. Alternatively, you can directly use the `close` method.
|
90
|
+
|
91
|
+
Attributes:
|
92
|
+
quantum_program (Union[SerializedQuantumProgram, QuantumProgram]): The quantum program to execute.
|
93
|
+
execution_preferences (Optional[ExecutionPreferences]): Execution preferences for the Quantum Program.
|
94
|
+
"""
|
95
|
+
|
96
|
+
def __init__(
|
97
|
+
self,
|
98
|
+
quantum_program: Program,
|
99
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
100
|
+
):
|
101
|
+
self.program: QuantumProgram = _deserialize_program(quantum_program)
|
102
|
+
self.update_execution_preferences(execution_preferences)
|
103
|
+
# We never use classical_execution_code in ExecutionSession, and we don't want
|
104
|
+
# the conversion route to fail because cmain is expected in some cases
|
105
|
+
self.program.model.classical_execution_code = "dummy"
|
106
|
+
|
107
|
+
self._random_seed = self.program.model.execution_preferences.random_seed
|
108
|
+
self._rng = random.Random(self._random_seed) # noqa: S311
|
109
|
+
|
110
|
+
self._async_client = client().async_client()
|
111
|
+
|
112
|
+
self._session_id: str | None = None
|
113
|
+
|
114
|
+
def __enter__(self) -> "ExecutionSession":
|
115
|
+
return self
|
116
|
+
|
117
|
+
def __exit__(
|
118
|
+
self,
|
119
|
+
exc_type: Optional[type[BaseException]],
|
120
|
+
exc_val: Optional[BaseException],
|
121
|
+
exc_tb: Optional[TracebackType],
|
122
|
+
) -> None:
|
123
|
+
self.close()
|
124
|
+
|
125
|
+
def close(self) -> None:
|
126
|
+
"""
|
127
|
+
Close the session and clean up its resources.
|
128
|
+
"""
|
129
|
+
async_utils.run(self._async_client.aclose())
|
130
|
+
|
131
|
+
def get_session_id(self) -> str:
|
132
|
+
if self._session_id is None:
|
133
|
+
self._session_id = async_utils.run(
|
134
|
+
ApiWrapper.call_create_execution_session(
|
135
|
+
self.program, self._async_client
|
136
|
+
)
|
137
|
+
)
|
138
|
+
return self._session_id
|
139
|
+
|
140
|
+
def _execute(self, primitives_input: PrimitivesInput) -> ExecutionJob:
|
141
|
+
primitives_input.random_seed = self._random_seed
|
142
|
+
self._random_seed = self._rng.randint(0, 2**32 - 1)
|
143
|
+
result = async_utils.run(
|
144
|
+
ApiWrapper.call_create_session_job(
|
145
|
+
self.get_session_id(), primitives_input, self._async_client
|
146
|
+
)
|
147
|
+
)
|
148
|
+
return ExecutionJob(details=result)
|
149
|
+
|
150
|
+
def update_execution_preferences(
|
151
|
+
self, execution_preferences: Optional[ExecutionPreferences]
|
152
|
+
) -> None:
|
153
|
+
"""
|
154
|
+
Update the execution preferences for the session.
|
155
|
+
|
156
|
+
Args:
|
157
|
+
execution_preferences: The execution preferences to update.
|
158
|
+
|
159
|
+
Returns:
|
160
|
+
None
|
161
|
+
"""
|
162
|
+
if execution_preferences is not None:
|
163
|
+
self.program.model.execution_preferences = execution_preferences
|
164
|
+
|
165
|
+
def sample(self, parameters: Optional[ExecutionParams] = None) -> ExecutionDetails:
|
166
|
+
"""
|
167
|
+
Samples the quantum program with the given parameters, if any.
|
168
|
+
|
169
|
+
Args:
|
170
|
+
parameters: The values to set for the parameters of the quantum program when sampling. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
171
|
+
|
172
|
+
Returns:
|
173
|
+
The result of the sampling.
|
174
|
+
"""
|
175
|
+
job = self.submit_sample(parameters=parameters)
|
176
|
+
return job.get_sample_result(_http_client=self._async_client)
|
177
|
+
|
178
|
+
def submit_sample(
|
179
|
+
self, parameters: Optional[ExecutionParams] = None
|
180
|
+
) -> ExecutionJob:
|
181
|
+
"""
|
182
|
+
Initiates an execution job with the `sample` primitive.
|
183
|
+
|
184
|
+
This is a non-blocking version of `sample`: it gets the same parameters and initiates the same execution job, but instead
|
185
|
+
of waiting for the result, it returns the job object immediately.
|
186
|
+
|
187
|
+
Args:
|
188
|
+
parameters: The values to set for the parameters of the quantum program when sampling. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
189
|
+
|
190
|
+
Returns:
|
191
|
+
The execution job.
|
192
|
+
"""
|
193
|
+
execution_primitives_input = PrimitivesInput(
|
194
|
+
sample=[parse_params(parameters)] if parameters is not None else [{}]
|
195
|
+
)
|
196
|
+
return self._execute(execution_primitives_input)
|
197
|
+
|
198
|
+
def batch_sample(self, parameters: list[ExecutionParams]) -> list[ExecutionDetails]:
|
199
|
+
"""
|
200
|
+
Samples the quantum program multiple times with the given parameters for each iteration. The number of samples is determined by the length of the parameters list.
|
201
|
+
|
202
|
+
Args:
|
203
|
+
parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
204
|
+
|
205
|
+
Returns:
|
206
|
+
List[ExecutionDetails]: The results of all the sampling iterations.
|
207
|
+
"""
|
208
|
+
job = self.submit_batch_sample(parameters=parameters)
|
209
|
+
return job.get_batch_sample_result(_http_client=self._async_client)
|
210
|
+
|
211
|
+
def submit_batch_sample(self, parameters: list[ExecutionParams]) -> ExecutionJob:
|
212
|
+
"""
|
213
|
+
Initiates an execution job with the `batch_sample` primitive.
|
214
|
+
|
215
|
+
This is a non-blocking version of `batch_sample`: it gets the same parameters and initiates the same execution job, but instead
|
216
|
+
of waiting for the result, it returns the job object immediately.
|
217
|
+
|
218
|
+
Args:
|
219
|
+
parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
220
|
+
|
221
|
+
Returns:
|
222
|
+
The execution job.
|
223
|
+
"""
|
224
|
+
execution_primitives_input = PrimitivesInput(
|
225
|
+
sample=[parse_params(params) for params in parameters]
|
226
|
+
)
|
227
|
+
return self._execute(execution_primitives_input)
|
228
|
+
|
229
|
+
def estimate(
|
230
|
+
self, hamiltonian: Hamiltonian, parameters: Optional[ExecutionParams] = None
|
231
|
+
) -> EstimationResult:
|
232
|
+
"""
|
233
|
+
Estimates the expectation value of the given Hamiltonian using the quantum program.
|
234
|
+
|
235
|
+
Args:
|
236
|
+
hamiltonian: The Hamiltonian to estimate the expectation value of.
|
237
|
+
parameters: The values to set for the parameters of the quantum program when estimating. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
238
|
+
|
239
|
+
Returns:
|
240
|
+
EstimationResult: The result of the estimation.
|
241
|
+
"""
|
242
|
+
job = self.submit_estimate(hamiltonian=hamiltonian, parameters=parameters)
|
243
|
+
return job.get_estimate_result(_http_client=self._async_client)
|
244
|
+
|
245
|
+
def submit_estimate(
|
246
|
+
self, hamiltonian: Hamiltonian, parameters: Optional[ExecutionParams] = None
|
247
|
+
) -> ExecutionJob:
|
248
|
+
"""
|
249
|
+
Initiates an execution job with the `estimate` primitive.
|
250
|
+
|
251
|
+
This is a non-blocking version of `estimate`: it gets the same parameters and initiates the same execution job, but instead
|
252
|
+
of waiting for the result, it returns the job object immediately.
|
253
|
+
|
254
|
+
Args:
|
255
|
+
hamiltonian: The Hamiltonian to estimate the expectation value of.
|
256
|
+
parameters: The values to set for the parameters of the quantum program when estimating. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
257
|
+
|
258
|
+
Returns:
|
259
|
+
The execution job.
|
260
|
+
"""
|
261
|
+
execution_primitives_input = PrimitivesInput(
|
262
|
+
estimate=EstimateInput(
|
263
|
+
hamiltonian=_hamiltonian_to_pauli_operator(hamiltonian),
|
264
|
+
parameters=(
|
265
|
+
[parse_params(parameters)] if parameters is not None else [{}]
|
266
|
+
),
|
267
|
+
)
|
268
|
+
)
|
269
|
+
return self._execute(execution_primitives_input)
|
270
|
+
|
271
|
+
def batch_estimate(
|
272
|
+
self, hamiltonian: Hamiltonian, parameters: list[ExecutionParams]
|
273
|
+
) -> list[EstimationResult]:
|
274
|
+
"""
|
275
|
+
Estimates the expectation value of the given Hamiltonian multiple times using the quantum program, with the given parameters for each iteration. The number of estimations is determined by the length of the parameters list.
|
276
|
+
|
277
|
+
Args:
|
278
|
+
hamiltonian: The Hamiltonian to estimate the expectation value of.
|
279
|
+
parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
280
|
+
|
281
|
+
Returns:
|
282
|
+
List[EstimationResult]: The results of all the estimation iterations.
|
283
|
+
"""
|
284
|
+
job = self.submit_batch_estimate(hamiltonian=hamiltonian, parameters=parameters)
|
285
|
+
return job.get_batch_estimate_result(_http_client=self._async_client)
|
286
|
+
|
287
|
+
def submit_batch_estimate(
|
288
|
+
self, hamiltonian: Hamiltonian, parameters: list[ExecutionParams]
|
289
|
+
) -> ExecutionJob:
|
290
|
+
"""
|
291
|
+
Initiates an execution job with the `batch_estimate` primitive.
|
292
|
+
|
293
|
+
This is a non-blocking version of `batch_estimate`: it gets the same parameters and initiates the same execution job, but instead
|
294
|
+
of waiting for the result, it returns the job object immediately.
|
295
|
+
|
296
|
+
Args:
|
297
|
+
hamiltonian: The Hamiltonian to estimate the expectation value of.
|
298
|
+
parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
|
299
|
+
|
300
|
+
Returns:
|
301
|
+
The execution job.
|
302
|
+
"""
|
303
|
+
execution_primitives_input = PrimitivesInput(
|
304
|
+
estimate=EstimateInput(
|
305
|
+
hamiltonian=_hamiltonian_to_pauli_operator(hamiltonian),
|
306
|
+
parameters=[parse_params(params) for params in parameters],
|
307
|
+
)
|
308
|
+
)
|
309
|
+
return self._execute(execution_primitives_input)
|
310
|
+
|
311
|
+
def estimate_cost(
|
312
|
+
self,
|
313
|
+
cost_func: Callable[[ParsedState], float],
|
314
|
+
parameters: Optional[ExecutionParams] = None,
|
315
|
+
quantile: float = 1.0,
|
316
|
+
) -> float:
|
317
|
+
"""
|
318
|
+
Estimates circuit cost using a classical cost function.
|
319
|
+
|
320
|
+
Args:
|
321
|
+
cost_func: classical circuit sample cost function
|
322
|
+
parameters: execution parameters sent to 'sample'
|
323
|
+
quantile: drop cost values outside the specified quantile
|
324
|
+
|
325
|
+
Returns:
|
326
|
+
cost estimation
|
327
|
+
|
328
|
+
See Also:
|
329
|
+
sample
|
330
|
+
"""
|
331
|
+
if quantile < 0 or quantile > 1:
|
332
|
+
raise ClassiqValueError("'quantile' must be between 0 and 1")
|
333
|
+
res = self.sample(parameters)
|
334
|
+
|
335
|
+
counts = np.array(res.parsed_counts)
|
336
|
+
costs = np.vectorize(lambda sample: cost_func(sample.state))(counts)
|
337
|
+
shots = np.vectorize(lambda sample: sample.shots)(counts)
|
338
|
+
|
339
|
+
if quantile == 1:
|
340
|
+
return float(np.average(costs, weights=shots))
|
341
|
+
costs = np.repeat(costs, shots)
|
342
|
+
sort_idx = costs.argsort()
|
343
|
+
sort_idx = sort_idx[: int(quantile * len(costs))]
|
344
|
+
costs = costs[sort_idx]
|
345
|
+
if costs.size == 0:
|
346
|
+
return np.nan
|
347
|
+
return float(np.average(costs))
|
348
|
+
|
349
|
+
def set_measured_state_filter(
|
350
|
+
self,
|
351
|
+
output_name: str,
|
352
|
+
condition: Callable,
|
353
|
+
) -> None:
|
354
|
+
"""
|
355
|
+
EXPERIMENTAL
|
356
|
+
|
357
|
+
When simulating on a statevector simulator, emulate the behavior of postprocessing
|
358
|
+
by discarding amplitudes for which their states are "undesirable".
|
359
|
+
|
360
|
+
Args:
|
361
|
+
output_name: The name of the register to filter
|
362
|
+
condition: Filter out values of the statevector for which this callable is False
|
363
|
+
"""
|
364
|
+
if self._session_id is not None:
|
365
|
+
raise ClassiqError(
|
366
|
+
"set_measured_state_filter must be called before use of the first primitive (sample, estimate...)"
|
367
|
+
)
|
368
|
+
|
369
|
+
if output_name not in self.program.model.circuit_outputs:
|
370
|
+
raise ClassiqValueError(f"{output_name} is not an output of the model")
|
371
|
+
output_type = self.program.model.circuit_output_types[output_name].quantum_types
|
372
|
+
|
373
|
+
legal_bitstrings = []
|
374
|
+
|
375
|
+
if isinstance(output_type, QuantumBit):
|
376
|
+
if condition(0):
|
377
|
+
legal_bitstrings.append("0")
|
378
|
+
if condition(1):
|
379
|
+
legal_bitstrings.append("1")
|
380
|
+
elif isinstance(output_type, QuantumNumeric):
|
381
|
+
size = output_type.size_in_bits
|
382
|
+
for i in range(2**size):
|
383
|
+
number_string = f"{i:0{size}b}"
|
384
|
+
val = number_utils.binary_to_float_or_int(
|
385
|
+
number_string,
|
386
|
+
output_type.fraction_digits_value,
|
387
|
+
output_type.sign_value,
|
388
|
+
)
|
389
|
+
if condition(val):
|
390
|
+
legal_bitstrings.append(number_string)
|
391
|
+
if len(legal_bitstrings) > 1:
|
392
|
+
raise NotImplementedError(
|
393
|
+
"Filtering is only supported on a single value per model output"
|
394
|
+
)
|
395
|
+
else:
|
396
|
+
raise NotImplementedError(
|
397
|
+
"Filtering is only supported on QuantumBit and QuantumNumeric"
|
398
|
+
)
|
399
|
+
|
400
|
+
self.program.model.register_filter_bitstrings[output_name] = legal_bitstrings
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import time
|
2
|
+
import webbrowser
|
3
|
+
|
4
|
+
from classiq.interface.exceptions import ClassiqError
|
5
|
+
from classiq.interface.execution.iqcc import IQCCInitAuthData, IQCCProbeAuthData
|
6
|
+
|
7
|
+
from classiq._internals.api_wrapper import ApiWrapper
|
8
|
+
from classiq._internals.async_utils import syncify_function
|
9
|
+
|
10
|
+
|
11
|
+
async def generate_iqcc_token_async(
|
12
|
+
auth_scope_id: str,
|
13
|
+
auth_method_id: str,
|
14
|
+
timeout: float = 120,
|
15
|
+
probe_interval: float = 1,
|
16
|
+
print_auth_url: bool = True,
|
17
|
+
) -> str:
|
18
|
+
"""Interactively generate a token for use in IQCC backends.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
auth_scope_id: The ID of the IQCC Boundary authentication scope.
|
22
|
+
auth_method_id: The ID of the IQCC Boundary authentication method.
|
23
|
+
timeout: Number of seconds to wait for the interactive authentication to complete.
|
24
|
+
probe_interval: Number of seconds to wait between probes of the authentication.
|
25
|
+
print_auth_url: Whether to print the authentication URL, useful for headless machines with no browser.
|
26
|
+
|
27
|
+
Returns:
|
28
|
+
The authentication token string to use directly in `IQCCBackendPreferences`.
|
29
|
+
|
30
|
+
Raises:
|
31
|
+
ClassiqError: In case timeout has reached before a successful authentication.
|
32
|
+
"""
|
33
|
+
initiate_response = await ApiWrapper().call_iqcc_init_auth(
|
34
|
+
IQCCInitAuthData(auth_scope_id=auth_scope_id, auth_method_id=auth_method_id)
|
35
|
+
)
|
36
|
+
|
37
|
+
if print_auth_url:
|
38
|
+
print("Please proceed with authentication on your web browser.") # noqa: T201
|
39
|
+
print("If no window has opened, use this link to authenticate:") # noqa: T201
|
40
|
+
print(initiate_response.auth_url) # noqa: T201
|
41
|
+
|
42
|
+
webbrowser.open_new_tab(initiate_response.auth_url)
|
43
|
+
|
44
|
+
start_time = time.monotonic()
|
45
|
+
while True:
|
46
|
+
time.sleep(probe_interval)
|
47
|
+
probe_response = await ApiWrapper().call_iqcc_probe_auth(
|
48
|
+
IQCCProbeAuthData(
|
49
|
+
auth_scope_id=auth_scope_id,
|
50
|
+
auth_method_id=auth_method_id,
|
51
|
+
token_id=initiate_response.token_id,
|
52
|
+
)
|
53
|
+
)
|
54
|
+
if probe_response is not None:
|
55
|
+
return probe_response.auth_token
|
56
|
+
|
57
|
+
if time.monotonic() - start_time > timeout:
|
58
|
+
raise ClassiqError(
|
59
|
+
f"Timeout has reached while probing IQCC authentication. Please try again and make sure to authenticate within {timeout} seconds, or increase the timeout."
|
60
|
+
)
|
61
|
+
|
62
|
+
|
63
|
+
generate_iqcc_token = syncify_function(generate_iqcc_token_async)
|