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
classiq/execution/jobs.py
CHANGED
@@ -1,24 +1,39 @@
|
|
1
1
|
import webbrowser
|
2
2
|
from datetime import datetime
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Optional, Union
|
4
4
|
from urllib.parse import urljoin
|
5
5
|
|
6
|
+
import httpx
|
7
|
+
|
8
|
+
from classiq.interface.exceptions import (
|
9
|
+
ClassiqAPIError,
|
10
|
+
ClassiqError,
|
11
|
+
)
|
6
12
|
from classiq.interface.execution.jobs import ExecutionJobDetailsV1
|
7
|
-
from classiq.interface.executor.execution_request import ExecutionJobDetails
|
13
|
+
from classiq.interface.executor.execution_request import ExecutionJobDetails, JobCost
|
8
14
|
from classiq.interface.executor.execution_result import ResultsCollection
|
15
|
+
from classiq.interface.executor.result import (
|
16
|
+
EstimationResult,
|
17
|
+
EstimationResults,
|
18
|
+
ExecutionDetails,
|
19
|
+
MultipleExecutionDetails,
|
20
|
+
)
|
9
21
|
from classiq.interface.jobs import JobStatus, JSONObject
|
10
|
-
from classiq.interface.server.routes import
|
22
|
+
from classiq.interface.server.routes import EXECUTION_JOBS_FULL_PATH
|
11
23
|
|
12
|
-
from classiq._internals.api_wrapper import
|
24
|
+
from classiq._internals.api_wrapper import ApiWrapper
|
13
25
|
from classiq._internals.async_utils import syncify_function
|
14
26
|
from classiq._internals.client import client
|
15
27
|
from classiq._internals.jobs import JobID, JobPoller
|
16
|
-
from classiq.exceptions import ClassiqAPIError
|
17
28
|
|
18
29
|
_JobDetails = Union[ExecutionJobDetails, ExecutionJobDetailsV1]
|
19
30
|
|
20
|
-
|
21
|
-
|
31
|
+
|
32
|
+
class ClassiqExecutionResultError(ClassiqError):
|
33
|
+
def __init__(self, primitive: str) -> None:
|
34
|
+
super().__init__(
|
35
|
+
f"Execution job does not contain a single {primitive!r} result, make sure you use the 'get_*_result' method matching the primitive you executed. You can use the 'result' method to see the general result."
|
36
|
+
)
|
22
37
|
|
23
38
|
|
24
39
|
class ExecutionJob:
|
@@ -76,23 +91,44 @@ class ExecutionJob:
|
|
76
91
|
else:
|
77
92
|
return f"{class_name}(name={self.name!r}, id={self.id!r})"
|
78
93
|
|
94
|
+
def cost(self, *, verbose: bool = False) -> Union[str, JobCost]:
|
95
|
+
if self._details.cost is None:
|
96
|
+
self._details.cost = JobCost()
|
97
|
+
if verbose:
|
98
|
+
return self._details.cost
|
99
|
+
return f"{self._details.cost.total_cost} {self._details.cost.currency_code}"
|
100
|
+
|
79
101
|
@classmethod
|
80
|
-
async def from_id_async(
|
81
|
-
|
102
|
+
async def from_id_async(
|
103
|
+
cls,
|
104
|
+
id: str,
|
105
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
106
|
+
) -> "ExecutionJob":
|
107
|
+
details = await ApiWrapper.call_get_execution_job_details(
|
108
|
+
JobID(job_id=id), http_client=_http_client
|
109
|
+
)
|
82
110
|
return cls(details)
|
83
111
|
|
112
|
+
# `syncify_function` doesn't work well for class methods, so I wrote `from_id`
|
113
|
+
# explicitly
|
84
114
|
@classmethod
|
85
|
-
def from_id(
|
86
|
-
|
115
|
+
def from_id(
|
116
|
+
cls,
|
117
|
+
id: str,
|
118
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
119
|
+
) -> "ExecutionJob":
|
120
|
+
return syncify_function(cls.from_id_async)(id, _http_client=_http_client)
|
87
121
|
|
88
122
|
@property
|
89
123
|
def _job_id(self) -> JobID:
|
90
124
|
return JobID(job_id=self.id)
|
91
125
|
|
92
126
|
async def result_async(
|
93
|
-
self,
|
127
|
+
self,
|
128
|
+
timeout_sec: Optional[float] = None,
|
129
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
94
130
|
) -> ResultsCollection:
|
95
|
-
await self.poll_async(timeout_sec=timeout_sec)
|
131
|
+
await self.poll_async(timeout_sec=timeout_sec, _http_client=_http_client)
|
96
132
|
|
97
133
|
if self.status == JobStatus.FAILED:
|
98
134
|
raise ClassiqAPIError(self.error or "")
|
@@ -102,45 +138,181 @@ class ExecutionJob:
|
|
102
138
|
if self._result is None:
|
103
139
|
self._result = (
|
104
140
|
await ApiWrapper.call_get_execution_job_result(
|
105
|
-
job_id=self._job_id,
|
141
|
+
job_id=self._job_id,
|
142
|
+
http_client=_http_client,
|
106
143
|
)
|
107
144
|
).results
|
108
145
|
return self._result
|
109
146
|
|
110
147
|
result = syncify_function(result_async)
|
111
148
|
|
112
|
-
|
149
|
+
def result_value(self, *args: Any, **kwargs: Any) -> Any:
|
150
|
+
return self.result(*args, **kwargs)[0].value
|
151
|
+
|
152
|
+
def get_sample_result(
|
153
|
+
self, _http_client: Optional[httpx.AsyncClient] = None
|
154
|
+
) -> ExecutionDetails:
|
155
|
+
"""
|
156
|
+
Returns the job's result as a single sample result after validation. If the result is not yet available, waits for it.
|
157
|
+
|
158
|
+
Returns:
|
159
|
+
The sample result of the execution job.
|
160
|
+
|
161
|
+
Raises:
|
162
|
+
ClassiqExecutionResultError: In case the result does not contain a single sample result.
|
163
|
+
ClassiqAPIError: In case the job has failed.
|
164
|
+
"""
|
165
|
+
results = self.result(_http_client=_http_client)
|
166
|
+
if len(results) != 1:
|
167
|
+
raise ClassiqExecutionResultError("sample")
|
168
|
+
|
169
|
+
result = results[0].value
|
170
|
+
if isinstance(result, ExecutionDetails):
|
171
|
+
return result
|
172
|
+
if isinstance(result, MultipleExecutionDetails) and len(result.details) == 1:
|
173
|
+
return result.details[0]
|
174
|
+
raise ClassiqExecutionResultError("sample")
|
175
|
+
|
176
|
+
def get_batch_sample_result(
|
177
|
+
self, _http_client: Optional[httpx.AsyncClient] = None
|
178
|
+
) -> list[ExecutionDetails]:
|
179
|
+
"""
|
180
|
+
Returns the job's result as a single batch_sample result after validation. If the result is not yet available, waits for it.
|
181
|
+
|
182
|
+
Returns:
|
183
|
+
The batch_sample result of the execution job.
|
184
|
+
|
185
|
+
Raises:
|
186
|
+
ClassiqExecutionResultError: In case the result does not contain a single batch_sample result.
|
187
|
+
ClassiqAPIError: In case the job has failed.
|
188
|
+
"""
|
189
|
+
results = self.result(_http_client=_http_client)
|
190
|
+
if len(results) != 1:
|
191
|
+
raise ClassiqExecutionResultError("batch_sample")
|
192
|
+
|
193
|
+
result = results[0].value
|
194
|
+
if isinstance(result, ExecutionDetails):
|
195
|
+
return [result]
|
196
|
+
if isinstance(result, MultipleExecutionDetails):
|
197
|
+
return result.details
|
198
|
+
|
199
|
+
raise ClassiqExecutionResultError("batch_sample")
|
200
|
+
|
201
|
+
def get_estimate_result(
|
202
|
+
self, _http_client: Optional[httpx.AsyncClient] = None
|
203
|
+
) -> EstimationResult:
|
204
|
+
"""
|
205
|
+
Returns the job's result as a single estimate result after validation. If the result is not yet available, waits for it.
|
206
|
+
|
207
|
+
Returns:
|
208
|
+
The estimate result of the execution job.
|
209
|
+
|
210
|
+
Raises:
|
211
|
+
ClassiqExecutionResultError: In case the result does not contain a single estimate result.
|
212
|
+
ClassiqAPIError: In case the job has failed.
|
213
|
+
"""
|
214
|
+
results = self.result(_http_client=_http_client)
|
215
|
+
if len(results) != 1:
|
216
|
+
raise ClassiqExecutionResultError("estimate")
|
217
|
+
|
218
|
+
result = results[0].value
|
219
|
+
if isinstance(result, EstimationResult):
|
220
|
+
return result
|
221
|
+
if isinstance(result, EstimationResults) and len(result.results) == 1:
|
222
|
+
return result.results[0]
|
223
|
+
raise ClassiqExecutionResultError("estimate")
|
224
|
+
|
225
|
+
def get_batch_estimate_result(
|
226
|
+
self, _http_client: Optional[httpx.AsyncClient] = None
|
227
|
+
) -> list[EstimationResult]:
|
228
|
+
"""
|
229
|
+
Returns the job's result as a single batch_estimate result after validation. If the result is not yet available, waits for it.
|
230
|
+
|
231
|
+
Returns:
|
232
|
+
The batch_estimate result of the execution job.
|
233
|
+
|
234
|
+
Raises:
|
235
|
+
ClassiqExecutionResultError: In case the result does not contain a single batch_estimate result.
|
236
|
+
ClassiqAPIError: In case the job has failed.
|
237
|
+
"""
|
238
|
+
results = self.result(_http_client=_http_client)
|
239
|
+
if len(results) != 1:
|
240
|
+
raise ClassiqExecutionResultError("batch_estimate")
|
241
|
+
|
242
|
+
result = results[0].value
|
243
|
+
if isinstance(result, EstimationResult):
|
244
|
+
return [result]
|
245
|
+
if isinstance(result, EstimationResults):
|
246
|
+
return result.results
|
247
|
+
|
248
|
+
raise ClassiqExecutionResultError("batch_estimate")
|
249
|
+
|
250
|
+
async def poll_async(
|
251
|
+
self,
|
252
|
+
timeout_sec: Optional[float] = None,
|
253
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
254
|
+
) -> None:
|
113
255
|
if not self.status.is_final():
|
114
|
-
await self._poll_job(timeout_sec=timeout_sec)
|
256
|
+
await self._poll_job(timeout_sec=timeout_sec, _http_client=_http_client)
|
115
257
|
|
116
258
|
poll = syncify_function(poll_async)
|
117
259
|
|
118
|
-
async def _poll_job(
|
260
|
+
async def _poll_job(
|
261
|
+
self,
|
262
|
+
timeout_sec: Optional[float] = None,
|
263
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
264
|
+
) -> None:
|
119
265
|
def response_parser(json_response: JSONObject) -> Optional[bool]:
|
120
|
-
self._details = ExecutionJobDetails.
|
266
|
+
self._details = ExecutionJobDetails.model_validate(json_response)
|
121
267
|
if self.status.is_final():
|
122
268
|
return True
|
123
269
|
return None
|
124
270
|
|
125
271
|
poller = JobPoller(
|
126
|
-
base_url=
|
127
|
-
use_versioned_url=False,
|
128
|
-
additional_headers={CLASSIQ_ACCEPT_HEADER: _JOB_DETAILS_VERSION},
|
272
|
+
base_url=EXECUTION_JOBS_FULL_PATH,
|
129
273
|
)
|
130
274
|
await poller.poll(
|
131
275
|
job_id=self._job_id,
|
132
276
|
response_parser=response_parser,
|
133
277
|
timeout_sec=timeout_sec,
|
278
|
+
http_client=_http_client,
|
134
279
|
)
|
135
280
|
|
136
|
-
async def rename_async(
|
137
|
-
self
|
281
|
+
async def rename_async(
|
282
|
+
self,
|
283
|
+
name: str,
|
284
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
285
|
+
) -> None:
|
286
|
+
self._details = await ApiWrapper.call_patch_execution_job(
|
287
|
+
self._job_id,
|
288
|
+
name,
|
289
|
+
http_client=_http_client,
|
290
|
+
)
|
138
291
|
|
139
292
|
rename = syncify_function(rename_async)
|
140
293
|
|
294
|
+
async def cancel_async(
|
295
|
+
self,
|
296
|
+
_http_client: Optional[httpx.AsyncClient] = None,
|
297
|
+
) -> None:
|
298
|
+
"""
|
299
|
+
Cancels the execution job. This implies the cancellation of any ongoing jobs
|
300
|
+
sent to the provider during this execution job.
|
301
|
+
|
302
|
+
The function returns without waiting to the actual cancellation. It is possible
|
303
|
+
to continue polling the job in order to ensure its cancellation, which might
|
304
|
+
not be immediate.
|
305
|
+
"""
|
306
|
+
await ApiWrapper.call_cancel_execution_job(
|
307
|
+
self._job_id,
|
308
|
+
http_client=_http_client,
|
309
|
+
)
|
310
|
+
|
311
|
+
cancel = syncify_function(cancel_async)
|
312
|
+
|
141
313
|
@property
|
142
314
|
def ide_url(self) -> str:
|
143
|
-
base_url = client().config.ide
|
315
|
+
base_url = client().config.ide.unicode_string()
|
144
316
|
return urljoin(base_url, f"jobs/{self.id}")
|
145
317
|
|
146
318
|
def open_in_ide(self) -> None:
|
@@ -149,7 +321,7 @@ class ExecutionJob:
|
|
149
321
|
|
150
322
|
async def get_execution_jobs_async(
|
151
323
|
offset: int = 0, limit: int = 50
|
152
|
-
) ->
|
324
|
+
) -> list[ExecutionJob]:
|
153
325
|
result = await ApiWrapper().call_query_execution_jobs(offset=offset, limit=limit)
|
154
326
|
return [ExecutionJob(details) for details in result.results]
|
155
327
|
|
classiq/execution/qnn.py
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
import functools
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
import more_itertools
|
5
|
+
|
6
|
+
from classiq.interface.chemistry.operator import PauliOperator
|
7
|
+
from classiq.interface.executor.constants import DEFAULT_RESULT_NAME
|
8
|
+
from classiq.interface.executor.execution_result import (
|
9
|
+
ResultsCollection,
|
10
|
+
SavedResultValueType,
|
11
|
+
TaggedEstimationResult,
|
12
|
+
TaggedExecutionDetails,
|
13
|
+
)
|
14
|
+
from classiq.interface.executor.quantum_code import Arguments, MultipleArguments
|
15
|
+
|
16
|
+
from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
|
17
|
+
pauli_operator_to_hamiltonian,
|
18
|
+
)
|
19
|
+
from classiq.execution.execution_session import ExecutionSession
|
20
|
+
from classiq.synthesis import SerializedQuantumProgram
|
21
|
+
|
22
|
+
_MAX_ARGUMENTS_SIZE = 1024
|
23
|
+
|
24
|
+
|
25
|
+
def _execute_qnn_estimate(
|
26
|
+
session: ExecutionSession,
|
27
|
+
arguments: list[Arguments],
|
28
|
+
observable: PauliOperator,
|
29
|
+
) -> ResultsCollection:
|
30
|
+
hamiltonian = pauli_operator_to_hamiltonian(observable.pauli_list)
|
31
|
+
return [
|
32
|
+
TaggedEstimationResult(
|
33
|
+
name=DEFAULT_RESULT_NAME,
|
34
|
+
value=result,
|
35
|
+
value_type=SavedResultValueType.EstimationResult,
|
36
|
+
)
|
37
|
+
for result in session.batch_estimate(
|
38
|
+
hamiltonian=hamiltonian, parameters=arguments
|
39
|
+
)
|
40
|
+
]
|
41
|
+
|
42
|
+
|
43
|
+
def _execute_qnn_sample(
|
44
|
+
session: ExecutionSession,
|
45
|
+
arguments: list[Arguments],
|
46
|
+
) -> ResultsCollection:
|
47
|
+
return [
|
48
|
+
TaggedExecutionDetails(
|
49
|
+
name=DEFAULT_RESULT_NAME,
|
50
|
+
value=result,
|
51
|
+
value_type=SavedResultValueType.ExecutionDetails,
|
52
|
+
)
|
53
|
+
for result in session.batch_sample(arguments)
|
54
|
+
]
|
55
|
+
|
56
|
+
|
57
|
+
def execute_qnn(
|
58
|
+
quantum_program: SerializedQuantumProgram,
|
59
|
+
arguments: MultipleArguments,
|
60
|
+
observable: Optional[PauliOperator] = None,
|
61
|
+
) -> ResultsCollection:
|
62
|
+
with ExecutionSession(quantum_program) as session:
|
63
|
+
if observable:
|
64
|
+
execute_function = functools.partial(
|
65
|
+
_execute_qnn_estimate,
|
66
|
+
session=session,
|
67
|
+
observable=observable,
|
68
|
+
)
|
69
|
+
else:
|
70
|
+
execute_function = functools.partial(
|
71
|
+
_execute_qnn_sample,
|
72
|
+
session=session,
|
73
|
+
)
|
74
|
+
|
75
|
+
result: ResultsCollection = []
|
76
|
+
for chunk in more_itertools.chunked(arguments, _MAX_ARGUMENTS_SIZE):
|
77
|
+
chunk_result = execute_function(arguments=chunk)
|
78
|
+
result.extend(chunk_result)
|
79
|
+
return result
|
classiq/executor.py
CHANGED
@@ -1,134 +1,55 @@
|
|
1
1
|
"""Executor module, implementing facilities for executing quantum programs using Classiq platform."""
|
2
2
|
|
3
|
-
import
|
4
|
-
from typing import Optional, Tuple, Union
|
3
|
+
from typing import Union
|
5
4
|
|
6
|
-
import more_itertools
|
7
5
|
from typing_extensions import TypeAlias
|
8
6
|
|
9
7
|
from classiq.interface.backend.backend_preferences import BackendPreferencesTypes
|
10
|
-
from classiq.interface.chemistry.operator import PauliOperators
|
11
8
|
from classiq.interface.executor.estimation import OperatorsEstimation
|
12
9
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
13
|
-
from classiq.interface.executor.
|
14
|
-
EstimateOperatorsExecution,
|
15
|
-
ExecutionRequest,
|
16
|
-
)
|
17
|
-
from classiq.interface.executor.execution_result import (
|
18
|
-
ResultsCollection,
|
19
|
-
SavedResultValueType,
|
20
|
-
TaggedEstimationResult,
|
21
|
-
TaggedExecutionDetails,
|
22
|
-
)
|
10
|
+
from classiq.interface.executor.quantum_code import QuantumCode
|
23
11
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
24
|
-
from classiq.interface.executor.quantum_program import MultipleArguments, QuantumProgram
|
25
12
|
from classiq.interface.executor.result import ExecutionDetails
|
26
|
-
from classiq.interface.generator.
|
13
|
+
from classiq.interface.generator.quantum_program import QuantumProgram
|
27
14
|
|
15
|
+
from classiq._internals import async_utils
|
28
16
|
from classiq._internals.api_wrapper import ApiWrapper
|
29
|
-
from classiq._internals.async_utils import syncify_function
|
30
17
|
from classiq.execution.jobs import ExecutionJob
|
31
|
-
from classiq.model.model import DEFAULT_RESULT_NAME
|
32
18
|
from classiq.synthesis import SerializedQuantumProgram
|
33
19
|
|
34
20
|
BatchExecutionResult: TypeAlias = Union[ExecutionDetails, BaseException]
|
35
|
-
ProgramAndResult: TypeAlias =
|
36
|
-
BackendPreferencesAndResult: TypeAlias =
|
21
|
+
ProgramAndResult: TypeAlias = tuple[QuantumCode, BatchExecutionResult]
|
22
|
+
BackendPreferencesAndResult: TypeAlias = tuple[
|
37
23
|
BackendPreferencesTypes, int, BatchExecutionResult
|
38
24
|
]
|
39
|
-
_MAX_ARGUMENTS_SIZE = 1024
|
40
25
|
|
41
26
|
|
42
27
|
def _parse_serialized_qprog(
|
43
28
|
quantum_program: SerializedQuantumProgram,
|
44
|
-
) ->
|
45
|
-
return
|
29
|
+
) -> QuantumProgram:
|
30
|
+
return QuantumProgram.model_validate_json(quantum_program)
|
46
31
|
|
47
32
|
|
48
33
|
async def execute_async(quantum_program: SerializedQuantumProgram) -> ExecutionJob:
|
49
34
|
circuit = _parse_serialized_qprog(quantum_program)
|
50
|
-
|
35
|
+
execution_input = await ApiWrapper.call_convert_quantum_program(circuit)
|
36
|
+
result = await ApiWrapper.call_execute_execution_input(execution_input)
|
51
37
|
return ExecutionJob(details=result)
|
52
38
|
|
53
39
|
|
54
|
-
execute
|
55
|
-
|
56
|
-
|
57
|
-
async def _execute_qnn_async_estimate(
|
58
|
-
quantum_program: QuantumProgram,
|
59
|
-
execution_preferences: ExecutionPreferences,
|
60
|
-
observables: PauliOperators,
|
61
|
-
) -> ResultsCollection:
|
62
|
-
request = ExecutionRequest(
|
63
|
-
execution_payload=EstimateOperatorsExecution(
|
64
|
-
quantum_program=quantum_program,
|
65
|
-
operators=observables,
|
66
|
-
),
|
67
|
-
preferences=execution_preferences,
|
68
|
-
)
|
69
|
-
|
70
|
-
results = await ApiWrapper.call_execute_estimate(request)
|
71
|
-
return [
|
72
|
-
TaggedEstimationResult(
|
73
|
-
name=DEFAULT_RESULT_NAME,
|
74
|
-
value=result,
|
75
|
-
value_type=SavedResultValueType.EstimationResult,
|
76
|
-
)
|
77
|
-
for result in results
|
78
|
-
]
|
79
|
-
|
80
|
-
|
81
|
-
async def _execute_qnn_async_program(
|
82
|
-
quantum_program: QuantumProgram,
|
83
|
-
execution_preferences: ExecutionPreferences,
|
84
|
-
) -> ResultsCollection:
|
85
|
-
request = ExecutionRequest(
|
86
|
-
execution_payload=quantum_program.dict(),
|
87
|
-
preferences=execution_preferences,
|
88
|
-
)
|
89
|
-
|
90
|
-
api_result = await ApiWrapper.call_execute_quantum_program(request)
|
91
|
-
return [
|
92
|
-
TaggedExecutionDetails(
|
93
|
-
name=DEFAULT_RESULT_NAME,
|
94
|
-
value=result,
|
95
|
-
value_type=SavedResultValueType.ExecutionDetails,
|
96
|
-
)
|
97
|
-
for result in api_result.details
|
98
|
-
]
|
99
|
-
|
100
|
-
|
101
|
-
async def execute_qnn_async(
|
102
|
-
quantum_program: SerializedQuantumProgram,
|
103
|
-
arguments: MultipleArguments,
|
104
|
-
observables: Optional[PauliOperators] = None,
|
105
|
-
) -> ResultsCollection:
|
106
|
-
circuit = _parse_serialized_qprog(quantum_program)
|
107
|
-
execution_preferences = circuit.model.execution_preferences
|
108
|
-
|
109
|
-
legacy_quantum_program = circuit.to_program()
|
110
|
-
|
111
|
-
if observables:
|
112
|
-
execute_function = functools.partial(
|
113
|
-
_execute_qnn_async_estimate,
|
114
|
-
execution_preferences=execution_preferences,
|
115
|
-
observables=observables,
|
116
|
-
)
|
117
|
-
else:
|
118
|
-
execute_function = functools.partial(
|
119
|
-
_execute_qnn_async_program,
|
120
|
-
execution_preferences=execution_preferences,
|
121
|
-
)
|
40
|
+
def execute(quantum_program: SerializedQuantumProgram) -> ExecutionJob:
|
41
|
+
"""
|
42
|
+
Execute a quantum program. The preferences for execution are set on the quantum program using the method `set_execution_preferences`.
|
122
43
|
|
123
|
-
|
124
|
-
|
125
|
-
legacy_quantum_program.arguments = tuple(chunk)
|
126
|
-
chunk_result = await execute_function(quantum_program=legacy_quantum_program)
|
127
|
-
result.extend(chunk_result)
|
128
|
-
return result
|
44
|
+
Args:
|
45
|
+
quantum_program: The quantum program to execute. This is the result of the synthesize method.
|
129
46
|
|
47
|
+
Returns:
|
48
|
+
ExecutionJob: The result of the execution.
|
130
49
|
|
131
|
-
|
50
|
+
For examples please see [Execution Documentation](https://docs.classiq.io/latest/user-guide/execution/)
|
51
|
+
"""
|
52
|
+
return async_utils.run(execute_async(quantum_program))
|
132
53
|
|
133
54
|
|
134
55
|
def set_quantum_program_execution_preferences(
|
@@ -137,27 +58,12 @@ def set_quantum_program_execution_preferences(
|
|
137
58
|
) -> SerializedQuantumProgram:
|
138
59
|
circuit = _parse_serialized_qprog(quantum_program)
|
139
60
|
circuit.model.execution_preferences = preferences
|
140
|
-
return SerializedQuantumProgram(circuit.
|
141
|
-
|
142
|
-
|
143
|
-
def set_initial_values(
|
144
|
-
quantum_program: SerializedQuantumProgram,
|
145
|
-
**kwargs: int,
|
146
|
-
) -> SerializedQuantumProgram:
|
147
|
-
circuit = _parse_serialized_qprog(quantum_program)
|
148
|
-
circuit.initial_values = kwargs
|
149
|
-
|
150
|
-
# Validate the initial values by calling `get_registers_initialization`
|
151
|
-
circuit.get_registers_initialization(circuit.initial_values)
|
152
|
-
|
153
|
-
return SerializedQuantumProgram(circuit.json())
|
61
|
+
return SerializedQuantumProgram(circuit.model_dump_json())
|
154
62
|
|
155
63
|
|
156
64
|
__all__ = [
|
157
|
-
"QuantumProgram",
|
158
|
-
"QuantumInstructionSet",
|
159
|
-
"execute_qnn",
|
160
65
|
"OperatorsEstimation",
|
66
|
+
"QuantumCode",
|
67
|
+
"QuantumInstructionSet",
|
161
68
|
"set_quantum_program_execution_preferences",
|
162
|
-
"set_initial_values",
|
163
69
|
]
|
classiq/interface/_version.py
CHANGED
@@ -1,36 +1,45 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Annotated, Optional
|
2
2
|
|
3
3
|
import numpy
|
4
4
|
import pydantic
|
5
|
-
from pydantic import Field
|
5
|
+
from pydantic import ConfigDict, Field, StringConstraints
|
6
6
|
|
7
7
|
from classiq.interface.backend.quantum_backend_providers import AnalyzerProviderVendor
|
8
8
|
from classiq.interface.chemistry.ground_state_problem import MoleculeProblem
|
9
9
|
from classiq.interface.executor.optimizer_preferences import OptimizerPreferences
|
10
10
|
from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
|
11
|
-
from classiq.interface.generator.model.preferences.preferences import
|
11
|
+
from classiq.interface.generator.model.preferences.preferences import (
|
12
|
+
TranspilationOption,
|
13
|
+
)
|
12
14
|
from classiq.interface.hardware import Provider
|
13
15
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
14
16
|
|
15
17
|
MAX_KB_OF_FILE = 500
|
16
18
|
MAX_FILE_LENGTH = MAX_KB_OF_FILE * 1024
|
17
19
|
|
20
|
+
MAX_QUBITS = 100
|
21
|
+
MIN_QUBITS = 0
|
22
|
+
MAX_COUNTS = 1000
|
23
|
+
MAX_NUM_CLIFFORD = 1000
|
24
|
+
MAX_NAME_LENGTH = 100
|
25
|
+
|
18
26
|
|
19
27
|
class AnalysisParams(pydantic.BaseModel):
|
20
28
|
qasm: PydanticNonEmptyString = Field(..., max_length=MAX_FILE_LENGTH)
|
21
29
|
|
22
30
|
|
23
31
|
class HardwareListParams(pydantic.BaseModel):
|
24
|
-
devices: Optional[
|
32
|
+
devices: Optional[list[PydanticNonEmptyString]] = pydantic.Field(
|
25
33
|
default=None, description="Devices"
|
26
34
|
)
|
27
|
-
providers:
|
35
|
+
providers: list[Provider]
|
28
36
|
from_ide: bool = Field(default=False)
|
29
37
|
|
30
|
-
@pydantic.
|
38
|
+
@pydantic.field_validator("providers")
|
39
|
+
@classmethod
|
31
40
|
def set_default_providers(
|
32
|
-
cls, providers: Optional[
|
33
|
-
) ->
|
41
|
+
cls, providers: Optional[list[AnalyzerProviderVendor]]
|
42
|
+
) -> list[AnalyzerProviderVendor]:
|
34
43
|
if providers is None:
|
35
44
|
providers = list(AnalyzerProviderVendor)
|
36
45
|
return providers
|
@@ -38,13 +47,32 @@ class HardwareListParams(pydantic.BaseModel):
|
|
38
47
|
|
39
48
|
class AnalysisOptionalDevicesParams(HardwareListParams):
|
40
49
|
qubit_count: int = pydantic.Field(
|
41
|
-
default=...,
|
50
|
+
default=...,
|
51
|
+
description="number of qubits in the data",
|
52
|
+
ge=MIN_QUBITS,
|
53
|
+
le=MAX_QUBITS,
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
class GateNamsMapping(pydantic.BaseModel):
|
58
|
+
qasm_name: Annotated[
|
59
|
+
str, Annotated[str, StringConstraints(max_length=MAX_NAME_LENGTH)]
|
60
|
+
]
|
61
|
+
display_name: Annotated[
|
62
|
+
str, Annotated[str, StringConstraints(max_length=MAX_NAME_LENGTH)]
|
63
|
+
]
|
64
|
+
|
65
|
+
|
66
|
+
class LatexParams(AnalysisParams):
|
67
|
+
gate_names: list[GateNamsMapping] = pydantic.Field(
|
68
|
+
default=..., description="List of gate names as apper in the qasm"
|
42
69
|
)
|
43
70
|
|
44
71
|
|
45
72
|
class AnalysisHardwareTranspilationParams(pydantic.BaseModel):
|
46
|
-
hardware_data: Optional[SynthesisHardwareData]
|
47
|
-
|
73
|
+
hardware_data: Optional[SynthesisHardwareData] = None
|
74
|
+
random_seed: int
|
75
|
+
transpilation_option: TranspilationOption
|
48
76
|
|
49
77
|
|
50
78
|
class AnalysisHardwareListParams(AnalysisParams, HardwareListParams):
|
@@ -67,13 +95,18 @@ class CircuitAnalysisHardwareParams(AnalysisParams):
|
|
67
95
|
|
68
96
|
class AnalysisRBParams(pydantic.BaseModel):
|
69
97
|
hardware: str
|
70
|
-
counts:
|
71
|
-
|
98
|
+
counts: list[
|
99
|
+
dict[
|
100
|
+
str, Annotated[int, Annotated[int, Field(strict=True, gt=0, le=MAX_COUNTS)]]
|
101
|
+
]
|
102
|
+
]
|
103
|
+
num_clifford: list[
|
104
|
+
Annotated[int, Annotated[int, Field(strict=True, gt=0, le=MAX_NUM_CLIFFORD)]]
|
105
|
+
]
|
72
106
|
|
73
107
|
|
74
108
|
class ChemistryGenerationParams(pydantic.BaseModel):
|
75
|
-
|
76
|
-
title = "Chemistry"
|
109
|
+
model_config = ConfigDict(title="Chemistry")
|
77
110
|
|
78
111
|
molecule: MoleculeProblem = pydantic.Field(
|
79
112
|
title="Molecule",
|
@@ -87,7 +120,7 @@ class ChemistryGenerationParams(pydantic.BaseModel):
|
|
87
120
|
def initial_point(self) -> Optional[numpy.ndarray]:
|
88
121
|
if self.optimizer_preferences.initial_point is not None:
|
89
122
|
return numpy.ndarray(
|
90
|
-
self.optimizer_preferences.initial_point # type: ignore
|
123
|
+
self.optimizer_preferences.initial_point # type: ignore[arg-type]
|
91
124
|
)
|
92
125
|
else:
|
93
126
|
return None
|