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,6 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import logging
|
4
|
+
import warnings
|
5
|
+
from datetime import datetime
|
4
6
|
from typing import TYPE_CHECKING, Optional
|
5
7
|
|
6
8
|
import httpx
|
@@ -8,10 +10,10 @@ import pydantic
|
|
8
10
|
from packaging.version import Version
|
9
11
|
from pydantic import BaseModel
|
10
12
|
|
13
|
+
from classiq.interface.exceptions import ClassiqAPIError, ClassiqDeprecationWarning
|
14
|
+
from classiq.interface.interface_version import INTERFACE_VERSION
|
11
15
|
from classiq.interface.server.global_versions import DeprecationInfo, GlobalVersions
|
12
16
|
|
13
|
-
from classiq.exceptions import ClassiqAPIError
|
14
|
-
|
15
17
|
if TYPE_CHECKING:
|
16
18
|
from classiq._internals.client import Client
|
17
19
|
|
@@ -26,16 +28,32 @@ class HostVersions(BaseModel):
|
|
26
28
|
class HostChecker:
|
27
29
|
_UNKNOWN_VERSION = "0.0.0"
|
28
30
|
|
29
|
-
def __init__(
|
31
|
+
def __init__(
|
32
|
+
self,
|
33
|
+
client: Client,
|
34
|
+
client_version: str,
|
35
|
+
interface_version: str = INTERFACE_VERSION,
|
36
|
+
) -> None:
|
30
37
|
self._client = client
|
31
38
|
self._client_version = client_version
|
39
|
+
self._interface_version = interface_version
|
40
|
+
|
41
|
+
def _get_interface_version(self) -> Optional[str]:
|
42
|
+
global_interfaces = GlobalVersions.model_validate(
|
43
|
+
self._client.sync_call_api(
|
44
|
+
"get", "/interface_versions", use_versioned_url=False
|
45
|
+
)
|
46
|
+
)
|
47
|
+
return global_interfaces.deployed.get(self._interface_version, None)
|
32
48
|
|
33
49
|
def _get_host_version(self) -> str:
|
34
|
-
host = HostVersions.
|
50
|
+
host = HostVersions.model_validate(
|
51
|
+
self._client.sync_call_api("get", "/versions")
|
52
|
+
)
|
35
53
|
return host.classiq_interface
|
36
54
|
|
37
55
|
def _get_deprecation_info(self) -> Optional[DeprecationInfo]:
|
38
|
-
global_versions = GlobalVersions.
|
56
|
+
global_versions = GlobalVersions.model_validate(
|
39
57
|
self._client.sync_call_api("get", "/versions", use_versioned_url=False)
|
40
58
|
)
|
41
59
|
return global_versions.deprecated.get(self._client_version, None)
|
@@ -56,18 +74,16 @@ class HostChecker:
|
|
56
74
|
|
57
75
|
def check_host_version(self) -> None:
|
58
76
|
try:
|
59
|
-
|
77
|
+
interface_version = self._get_interface_version()
|
60
78
|
except httpx.ConnectError:
|
61
79
|
_logger.warning(
|
62
80
|
"Version check failed - host unavailable.",
|
63
81
|
)
|
64
82
|
else:
|
65
|
-
if
|
66
|
-
raw_host_version, self._client_version
|
67
|
-
):
|
83
|
+
if interface_version is None:
|
68
84
|
raise ClassiqAPIError(
|
69
|
-
f"
|
70
|
-
f"{
|
85
|
+
f"You are using an unsupported version of Classiq SDK - {self._client_version}. "
|
86
|
+
f"{_VERSION_UPDATE_SUGGESTION}"
|
71
87
|
)
|
72
88
|
|
73
89
|
def check_deprecated_version(self) -> None:
|
@@ -80,8 +96,15 @@ class HostChecker:
|
|
80
96
|
else:
|
81
97
|
if deprecation_info is None:
|
82
98
|
return
|
83
|
-
|
84
|
-
|
85
|
-
deprecation_info.removal_date
|
86
|
-
|
99
|
+
removal_date = (
|
100
|
+
deprecation_info.removal_date.date()
|
101
|
+
if isinstance(deprecation_info.removal_date, datetime)
|
102
|
+
else deprecation_info.removal_date
|
103
|
+
)
|
104
|
+
warnings.warn(
|
105
|
+
f"The current version of 'classiq' has been deprecated, and"
|
106
|
+
f" will not be supported as of {removal_date}. "
|
107
|
+
f"{_VERSION_UPDATE_SUGGESTION}",
|
108
|
+
ClassiqDeprecationWarning,
|
109
|
+
stacklevel=2,
|
87
110
|
)
|
classiq/_internals/jobs.py
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
import json
|
2
2
|
import logging
|
3
|
-
from
|
3
|
+
from collections.abc import Iterable
|
4
|
+
from typing import Callable, Optional, TypeVar
|
4
5
|
|
5
6
|
import httpx
|
6
7
|
import pydantic
|
7
8
|
|
9
|
+
from classiq.interface.exceptions import ClassiqAPIError
|
8
10
|
from classiq.interface.jobs import JobDescription, JobID, JSONObject
|
9
11
|
|
10
12
|
from classiq._internals.async_utils import poll_for
|
11
|
-
from classiq._internals.client import client
|
13
|
+
from classiq._internals.client import client
|
12
14
|
from classiq._internals.config import SDKMode
|
13
|
-
from classiq.exceptions import ClassiqAPIError
|
14
15
|
|
15
16
|
_URL_PATH_SEP = "/"
|
16
17
|
GeneralJobDescription = JobDescription[JSONObject]
|
@@ -37,28 +38,24 @@ def _join_url_path(*parts: str) -> str:
|
|
37
38
|
def _general_job_description_parser(
|
38
39
|
json_response: JSONObject,
|
39
40
|
) -> Optional[GeneralJobDescription]:
|
40
|
-
job_description
|
41
|
-
json_response
|
42
|
-
)
|
41
|
+
job_description = GeneralJobDescription.model_validate(json_response)
|
43
42
|
if job_description.status.is_final():
|
44
43
|
return job_description
|
45
44
|
return None
|
46
45
|
|
47
46
|
|
48
47
|
class JobPoller:
|
49
|
-
INITIAL_INTERVAL_SEC = 1
|
50
|
-
INTERVAL_FACTOR =
|
51
|
-
FINAL_INTERVAL_SEC =
|
48
|
+
INITIAL_INTERVAL_SEC = 0.1
|
49
|
+
INTERVAL_FACTOR = 1.5
|
50
|
+
FINAL_INTERVAL_SEC = 25
|
52
51
|
DEV_INTERVAL = 0.05
|
53
52
|
|
54
53
|
def __init__(
|
55
54
|
self,
|
56
55
|
base_url: str,
|
57
|
-
required_headers: Optional[Set[str]] = None,
|
58
56
|
use_versioned_url: bool = True,
|
59
|
-
additional_headers: Optional[
|
57
|
+
additional_headers: Optional[dict[str, str]] = None,
|
60
58
|
) -> None:
|
61
|
-
self._required_headers = required_headers or set()
|
62
59
|
self._additional_headers = additional_headers
|
63
60
|
client_instance = client()
|
64
61
|
self._base_url = (
|
@@ -66,11 +63,10 @@ class JobPoller:
|
|
66
63
|
if use_versioned_url
|
67
64
|
else base_url
|
68
65
|
)
|
69
|
-
self._async_client = client_instance.async_client()
|
70
66
|
self._mode = client_instance.config.mode
|
71
67
|
|
72
68
|
def _parse_job_id_response(self, response: httpx.Response) -> JobID:
|
73
|
-
return JobID.
|
69
|
+
return JobID.model_validate(response.json())
|
74
70
|
|
75
71
|
def _make_poll_url(self, job_id: JobID) -> str:
|
76
72
|
return _join_url_path(self._base_url, job_id.job_id)
|
@@ -79,37 +75,33 @@ class JobPoller:
|
|
79
75
|
def _make_cancel_url(poll_url: str) -> str:
|
80
76
|
return _join_url_path(poll_url, "cancel")
|
81
77
|
|
82
|
-
def _update_headers(self, response: httpx.Response) -> None:
|
83
|
-
for header in self._required_headers:
|
84
|
-
try:
|
85
|
-
self._async_client.headers[header] = response.headers[header]
|
86
|
-
except KeyError as exc:
|
87
|
-
raise ClassiqAPIError(
|
88
|
-
f"Response to {self._base_url} is missing header {header}"
|
89
|
-
) from exc
|
90
|
-
|
91
|
-
@try_again_on_failure
|
92
78
|
async def _request(
|
93
|
-
self,
|
79
|
+
self,
|
80
|
+
http_client: httpx.AsyncClient,
|
81
|
+
http_method: str,
|
82
|
+
url: str,
|
83
|
+
body: Optional[dict] = None,
|
94
84
|
) -> httpx.Response:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
85
|
+
return await client().request(
|
86
|
+
http_client=http_client,
|
87
|
+
method=http_method,
|
88
|
+
url=url,
|
89
|
+
json=body,
|
90
|
+
headers=self._additional_headers,
|
99
91
|
)
|
100
|
-
client().handle_response(response)
|
101
|
-
return response
|
102
92
|
|
103
|
-
async def _submit(
|
104
|
-
|
93
|
+
async def _submit(
|
94
|
+
self, http_client: httpx.AsyncClient, body: dict
|
95
|
+
) -> httpx.Response:
|
96
|
+
return await self._request(
|
97
|
+
http_client=http_client, http_method="POST", url=self._base_url, body=body
|
98
|
+
)
|
105
99
|
|
106
100
|
def _interval_sec(self) -> Iterable[float]:
|
107
101
|
if self._mode == SDKMode.DEV:
|
108
102
|
while True:
|
109
103
|
yield self.DEV_INTERVAL
|
110
104
|
else:
|
111
|
-
for _ in range(10):
|
112
|
-
yield self.INITIAL_INTERVAL_SEC
|
113
105
|
interval = self.INITIAL_INTERVAL_SEC
|
114
106
|
while True:
|
115
107
|
yield interval
|
@@ -117,13 +109,16 @@ class JobPoller:
|
|
117
109
|
|
118
110
|
async def _poll(
|
119
111
|
self,
|
112
|
+
http_client: httpx.AsyncClient,
|
120
113
|
poll_url: str,
|
121
114
|
timeout_sec: Optional[float],
|
122
115
|
response_parser: Callable[[JSONObject], Optional[T]] = _general_job_description_parser, # type: ignore[assignment]
|
123
116
|
) -> T:
|
124
117
|
async def poller() -> JSONObject:
|
125
118
|
nonlocal self, poll_url
|
126
|
-
raw_response = await self._request(
|
119
|
+
raw_response = await self._request(
|
120
|
+
http_client=http_client, http_method="GET", url=poll_url
|
121
|
+
)
|
127
122
|
return raw_response.json()
|
128
123
|
|
129
124
|
async for json_response in poll_for(
|
@@ -139,39 +134,50 @@ class JobPoller:
|
|
139
134
|
job_id: JobID,
|
140
135
|
timeout_sec: Optional[float],
|
141
136
|
response_parser: Callable[[JSONObject], Optional[T]] = _general_job_description_parser, # type: ignore[assignment]
|
137
|
+
http_client: Optional[httpx.AsyncClient] = None,
|
142
138
|
) -> T:
|
143
139
|
poll_url = self._make_poll_url(job_id=job_id)
|
144
|
-
async with
|
140
|
+
async with client().use_client_or_create(http_client) as async_client:
|
145
141
|
return await self._poll(
|
142
|
+
http_client=async_client,
|
146
143
|
poll_url=poll_url,
|
147
144
|
response_parser=response_parser,
|
148
145
|
timeout_sec=timeout_sec,
|
149
146
|
)
|
150
147
|
|
151
|
-
async def _cancel(self, poll_url: str) -> None:
|
148
|
+
async def _cancel(self, http_client: httpx.AsyncClient, poll_url: str) -> None:
|
152
149
|
_logger.info("Cancelling job %s", poll_url, exc_info=True)
|
153
150
|
cancel_url = self._make_cancel_url(poll_url)
|
154
|
-
await self._request(http_method="PUT", url=cancel_url)
|
151
|
+
await self._request(http_client=http_client, http_method="PUT", url=cancel_url)
|
155
152
|
|
156
153
|
async def run(
|
157
|
-
self,
|
154
|
+
self,
|
155
|
+
body: dict,
|
156
|
+
timeout_sec: Optional[float],
|
157
|
+
http_client: Optional[httpx.AsyncClient] = None,
|
158
158
|
) -> GeneralJobDescription:
|
159
|
-
async with
|
160
|
-
submit_response = await self._submit(body=body)
|
159
|
+
async with client().use_client_or_create(http_client) as async_client:
|
160
|
+
submit_response = await self._submit(http_client=async_client, body=body)
|
161
161
|
job_id = self._parse_job_id_response(response=submit_response)
|
162
162
|
poll_url = self._make_poll_url(job_id=job_id)
|
163
|
-
self._update_headers(response=submit_response)
|
164
163
|
try:
|
165
|
-
return await self._poll(
|
164
|
+
return await self._poll(
|
165
|
+
http_client=async_client,
|
166
|
+
poll_url=poll_url,
|
167
|
+
timeout_sec=timeout_sec,
|
168
|
+
)
|
166
169
|
except Exception:
|
167
|
-
await self._cancel(poll_url=poll_url)
|
170
|
+
await self._cancel(http_client=async_client, poll_url=poll_url)
|
168
171
|
raise
|
169
172
|
|
170
173
|
async def run_pydantic(
|
171
|
-
self,
|
174
|
+
self,
|
175
|
+
model: pydantic.BaseModel,
|
176
|
+
timeout_sec: Optional[float],
|
177
|
+
http_client: Optional[httpx.AsyncClient] = None,
|
172
178
|
) -> GeneralJobDescription:
|
173
179
|
# TODO: we can't use model.dict() - it doesn't serialize complex class.
|
174
|
-
# This was added because JSON serializer doesn't serialize complex
|
175
|
-
# We should add support for smarter json serialization.
|
176
|
-
body = json.loads(model.
|
177
|
-
return await self.run(body, timeout_sec)
|
180
|
+
# This was added because JSON serializer doesn't serialize complex and UUID,
|
181
|
+
# while pydantic does. We should add support for smarter json serialization.
|
182
|
+
body = json.loads(model.model_dump_json())
|
183
|
+
return await self.run(body, timeout_sec, http_client=http_client)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Any,
|
1
|
+
from typing import Any, TypeVar, Union, overload
|
2
2
|
|
3
3
|
T = TypeVar("T")
|
4
4
|
U = TypeVar("U")
|
@@ -10,37 +10,37 @@ U = TypeVar("U")
|
|
10
10
|
|
11
11
|
@overload
|
12
12
|
def validate_type(
|
13
|
-
obj: Any, expected_type:
|
13
|
+
obj: Any, expected_type: type[T], operation: str, exception_type: type[Exception]
|
14
14
|
) -> T: ...
|
15
15
|
|
16
16
|
|
17
17
|
@overload
|
18
18
|
def validate_type(
|
19
19
|
obj: Any,
|
20
|
-
expected_type:
|
20
|
+
expected_type: tuple[type[T], type[U]],
|
21
21
|
operation: str,
|
22
|
-
exception_type:
|
22
|
+
exception_type: type[Exception],
|
23
23
|
) -> Union[T, U]: ...
|
24
24
|
|
25
25
|
|
26
26
|
@overload
|
27
27
|
def validate_type(
|
28
28
|
obj: Any,
|
29
|
-
expected_type:
|
29
|
+
expected_type: tuple[type[T], ...],
|
30
30
|
operation: str,
|
31
|
-
exception_type:
|
31
|
+
exception_type: type[Exception],
|
32
32
|
) -> Any: ...
|
33
33
|
|
34
34
|
|
35
35
|
def validate_type(
|
36
36
|
obj: Any,
|
37
|
-
expected_type: Union[
|
37
|
+
expected_type: Union[tuple[type, ...], type],
|
38
38
|
operation: str,
|
39
|
-
exception_type:
|
39
|
+
exception_type: type[Exception],
|
40
40
|
) -> Any:
|
41
41
|
operation = operation[0].upper() + operation[1:]
|
42
42
|
if not isinstance(obj, expected_type):
|
43
|
-
expected_types:
|
43
|
+
expected_types: tuple[type, ...]
|
44
44
|
if isinstance(expected_type, type):
|
45
45
|
expected_types = (expected_type,)
|
46
46
|
else:
|
classiq/analyzer/__init__.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
1
|
import classiq.analyzer.show_interactive_hack
|
4
2
|
from classiq.analyzer.analyzer import Analyzer
|
5
3
|
|
@@ -8,5 +6,5 @@ from ..analyzer import rb
|
|
8
6
|
__all__ = ["rb"]
|
9
7
|
|
10
8
|
|
11
|
-
def __dir__() ->
|
9
|
+
def __dir__() -> list[str]:
|
12
10
|
return ["rb"]
|
classiq/analyzer/analyzer.py
CHANGED
@@ -2,28 +2,26 @@
|
|
2
2
|
|
3
3
|
import json
|
4
4
|
import webbrowser
|
5
|
+
from collections.abc import Sequence
|
5
6
|
from importlib.util import find_spec
|
6
|
-
from typing import Any,
|
7
|
+
from typing import Any, Optional, Union
|
7
8
|
from urllib.parse import urljoin
|
8
9
|
|
9
10
|
import plotly.graph_objects as go
|
10
11
|
|
11
12
|
from classiq.interface.analyzer import analysis_params
|
12
13
|
from classiq.interface.backend.quantum_backend_providers import AnalyzerProviderVendor
|
13
|
-
from classiq.interface.
|
14
|
+
from classiq.interface.exceptions import ClassiqAnalyzerError
|
15
|
+
from classiq.interface.generator import quantum_program as generator_result
|
14
16
|
|
15
|
-
from classiq._internals import client
|
17
|
+
from classiq._internals import async_utils, client
|
16
18
|
from classiq._internals.api_wrapper import ApiWrapper
|
17
|
-
from classiq._internals.async_utils import Asyncify
|
18
19
|
from classiq.analyzer.analyzer_utilities import (
|
19
20
|
AnalyzerUtilities,
|
20
21
|
DeviceName,
|
21
|
-
HardwareGraphs,
|
22
|
-
ProviderAvailableDevices,
|
23
22
|
ProviderNameEnum,
|
24
23
|
)
|
25
24
|
from classiq.analyzer.url_utils import circuit_page_uri, client_ide_base_url
|
26
|
-
from classiq.exceptions import ClassiqAnalyzerError
|
27
25
|
|
28
26
|
find_ipywidgets = find_spec("ipywidgets")
|
29
27
|
VBox = Any
|
@@ -34,39 +32,44 @@ if find_ipywidgets is not None:
|
|
34
32
|
from classiq._analyzer_extras.interactive_hardware import InteractiveHardware
|
35
33
|
|
36
34
|
|
37
|
-
class Analyzer(AnalyzerUtilities
|
35
|
+
class Analyzer(AnalyzerUtilities):
|
38
36
|
"""Analyzer is the wrapper object for all analysis capabilities."""
|
39
37
|
|
40
|
-
def __init__(self, circuit: generator_result.
|
38
|
+
def __init__(self, circuit: generator_result.QuantumProgram) -> None:
|
41
39
|
"""Init self.
|
42
40
|
|
43
41
|
Args:
|
44
|
-
circuit
|
42
|
+
circuit: The circuit to be analyzed.
|
45
43
|
"""
|
46
44
|
if circuit.qasm is None:
|
47
45
|
raise ClassiqAnalyzerError(
|
48
46
|
"Analysis requires a circuit with valid QASM code"
|
49
47
|
)
|
50
|
-
|
48
|
+
params: analysis_params.AnalysisParams = analysis_params.AnalysisParams(
|
51
49
|
qasm=circuit.qasm
|
52
50
|
)
|
53
|
-
|
51
|
+
super().__init__(
|
52
|
+
params=params,
|
53
|
+
circuit=circuit,
|
54
|
+
available_devices=dict(),
|
55
|
+
hardware_graphs=dict(),
|
56
|
+
)
|
57
|
+
|
54
58
|
self.hardware_comparison_table: Optional[go.Figure] = None
|
55
|
-
self.available_devices: ProviderAvailableDevices = dict()
|
56
|
-
self.hardware_graphs: HardwareGraphs = dict()
|
57
59
|
|
58
60
|
self.transpilation_params = analysis_params.AnalysisHardwareTranspilationParams(
|
59
61
|
hardware_data=self.circuit.hardware_data,
|
60
|
-
|
62
|
+
random_seed=self.circuit.model.execution_preferences.random_seed,
|
63
|
+
transpilation_option=self.circuit.model.execution_preferences.transpile_to_hardware,
|
61
64
|
)
|
62
65
|
|
63
|
-
|
66
|
+
def analyzer_app(self) -> None:
|
64
67
|
"""Opens the analyzer app with synthesis interactive results.
|
65
68
|
|
66
69
|
Returns:
|
67
70
|
None.
|
68
71
|
"""
|
69
|
-
result =
|
72
|
+
result = async_utils.run(ApiWrapper.call_analyzer_app(self.circuit))
|
70
73
|
webbrowser.open_new_tab(
|
71
74
|
urljoin(
|
72
75
|
client_ide_base_url(),
|
@@ -76,27 +79,29 @@ class Analyzer(AnalyzerUtilities, metaclass=Asyncify):
|
|
76
79
|
)
|
77
80
|
)
|
78
81
|
|
79
|
-
|
80
|
-
self, providers: Optional[
|
81
|
-
) ->
|
82
|
-
"""
|
82
|
+
def get_available_devices(
|
83
|
+
self, providers: Optional[list[ProviderNameEnum]] = None
|
84
|
+
) -> dict[ProviderNameEnum, list[DeviceName]]:
|
85
|
+
"""Deprecated. Use get_all_hardware_devices instead.
|
86
|
+
|
87
|
+
Returns dict of the available devices by the providers. only devices
|
83
88
|
with sufficient number of qubits are returns
|
84
89
|
|
85
|
-
Args: providers
|
90
|
+
Args: providers: List of providers.
|
86
91
|
if None, the table include all the available hardware.
|
87
92
|
|
88
93
|
Returns:
|
89
|
-
available devices
|
94
|
+
available devices: dict of the available devices.
|
90
95
|
"""
|
91
96
|
if providers is None:
|
92
97
|
providers = list(AnalyzerProviderVendor)
|
93
|
-
|
98
|
+
async_utils.run(self._request_available_devices_async(providers=providers))
|
94
99
|
return {
|
95
100
|
provider: self._filter_devices_by_qubits_count(provider)
|
96
101
|
for provider in providers
|
97
102
|
}
|
98
103
|
|
99
|
-
|
104
|
+
def plot_hardware_connectivity(
|
100
105
|
self,
|
101
106
|
provider: Optional[ProviderNameEnum] = None,
|
102
107
|
device: Optional[DeviceName] = None,
|
@@ -105,10 +110,10 @@ class Analyzer(AnalyzerUtilities, metaclass=Asyncify):
|
|
105
110
|
analyzer_sdk extra.
|
106
111
|
|
107
112
|
Args:
|
108
|
-
provider
|
109
|
-
device
|
113
|
+
provider: provider name.
|
114
|
+
device: device name.
|
110
115
|
Returns:
|
111
|
-
hardware_connectivity_graph
|
116
|
+
hardware_connectivity_graph: interactive graph.
|
112
117
|
"""
|
113
118
|
|
114
119
|
self._validate_analyzer_extra()
|
@@ -118,7 +123,7 @@ class Analyzer(AnalyzerUtilities, metaclass=Asyncify):
|
|
118
123
|
available_devices=self.available_devices,
|
119
124
|
hardware_graphs=self.hardware_graphs,
|
120
125
|
)
|
121
|
-
|
126
|
+
async_utils.run(interactive_hardware.enable_interactivity_async())
|
122
127
|
if provider is not None:
|
123
128
|
interactive_hardware.providers_combobox.value = provider
|
124
129
|
if device is not None:
|
@@ -126,19 +131,21 @@ class Analyzer(AnalyzerUtilities, metaclass=Asyncify):
|
|
126
131
|
|
127
132
|
return interactive_hardware.show_interactive_graph()
|
128
133
|
|
129
|
-
|
134
|
+
def get_hardware_comparison_table(
|
130
135
|
self,
|
131
136
|
providers: Optional[Sequence[Union[str, AnalyzerProviderVendor]]] = None,
|
132
|
-
devices: Optional[
|
137
|
+
devices: Optional[list[str]] = None,
|
133
138
|
) -> None:
|
134
139
|
"""create a comparison table between the transpiled circuits result on different hardware.
|
135
140
|
The comparison table included the depth, multi qubit gates count,and total gates count of the circuits.
|
136
141
|
|
137
|
-
Args:
|
138
|
-
|
139
|
-
|
142
|
+
Args:
|
143
|
+
providers: List of providers. if None, the table include all the available hardware.
|
144
|
+
devices: List of devices. if None, the table include all the available devices of the selected
|
140
145
|
providers.
|
141
|
-
|
146
|
+
|
147
|
+
Returns:
|
148
|
+
None.
|
142
149
|
"""
|
143
150
|
if providers is None:
|
144
151
|
providers = list(AnalyzerProviderVendor)
|
@@ -148,13 +155,13 @@ class Analyzer(AnalyzerUtilities, metaclass=Asyncify):
|
|
148
155
|
devices=devices,
|
149
156
|
transpilation_params=self.transpilation_params,
|
150
157
|
)
|
151
|
-
result =
|
158
|
+
result = async_utils.run(ApiWrapper.call_table_graphs_task(params=params))
|
152
159
|
self.hardware_comparison_table = go.Figure(json.loads(result.details))
|
153
160
|
|
154
|
-
|
161
|
+
def plot_hardware_comparison_table(
|
155
162
|
self,
|
156
|
-
providers: Optional[
|
157
|
-
devices: Optional[
|
163
|
+
providers: Optional[list[Union[str, AnalyzerProviderVendor]]] = None,
|
164
|
+
devices: Optional[list[str]] = None,
|
158
165
|
) -> None:
|
159
166
|
"""plot the comparison table. if it has not been created it, it first creates the table using all the
|
160
167
|
available hardware.
|
@@ -162,24 +169,20 @@ class Analyzer(AnalyzerUtilities, metaclass=Asyncify):
|
|
162
169
|
Returns:
|
163
170
|
None.
|
164
171
|
"""
|
165
|
-
|
166
|
-
providers=providers, devices=devices
|
167
|
-
)
|
172
|
+
self._hardware_comparison_condition(providers=providers, devices=devices)
|
168
173
|
self.hardware_comparison_table.show() # type: ignore[union-attr]
|
169
174
|
|
170
|
-
|
175
|
+
def _hardware_comparison_condition(
|
171
176
|
self,
|
172
177
|
providers: Optional[Sequence[Union[str, AnalyzerProviderVendor]]] = None,
|
173
|
-
devices: Optional[
|
178
|
+
devices: Optional[list[str]] = None,
|
174
179
|
) -> None:
|
175
180
|
if (
|
176
181
|
providers is not None
|
177
182
|
or devices is not None
|
178
183
|
or self.hardware_comparison_table is None
|
179
184
|
):
|
180
|
-
|
181
|
-
providers=providers, devices=devices
|
182
|
-
)
|
185
|
+
self.get_hardware_comparison_table(providers=providers, devices=devices)
|
183
186
|
|
184
187
|
@staticmethod
|
185
188
|
def _open_route(path: str) -> None:
|
@@ -1,11 +1,11 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Union
|
2
2
|
|
3
3
|
from classiq.interface.analyzer import analysis_params
|
4
4
|
from classiq.interface.backend.quantum_backend_providers import AnalyzerProviderVendor
|
5
|
-
from classiq.interface.
|
5
|
+
from classiq.interface.exceptions import ClassiqAnalyzerError
|
6
|
+
from classiq.interface.generator.quantum_program import QuantumProgram
|
6
7
|
|
7
8
|
from classiq._internals.api_wrapper import ApiWrapper
|
8
|
-
from classiq.exceptions import ClassiqAnalyzerError
|
9
9
|
|
10
10
|
DeviceName = str
|
11
11
|
ProviderName = str
|
@@ -13,26 +13,26 @@ ProviderLowerName = str
|
|
13
13
|
HardwareGraphJson = str
|
14
14
|
Availability = bool
|
15
15
|
ProviderNameEnum = Union[ProviderName, AnalyzerProviderVendor]
|
16
|
-
AvailableDevices =
|
17
|
-
ProviderAvailableDevices =
|
18
|
-
HardwareGraphs =
|
16
|
+
AvailableDevices = dict[DeviceName, Availability]
|
17
|
+
ProviderAvailableDevices = dict[ProviderLowerName, AvailableDevices]
|
18
|
+
HardwareGraphs = dict[DeviceName, HardwareGraphJson]
|
19
19
|
|
20
20
|
|
21
21
|
class AnalyzerUtilities:
|
22
22
|
def __init__(
|
23
23
|
self,
|
24
24
|
params: analysis_params.AnalysisParams,
|
25
|
-
circuit:
|
25
|
+
circuit: QuantumProgram,
|
26
26
|
available_devices: ProviderAvailableDevices,
|
27
27
|
hardware_graphs: HardwareGraphs,
|
28
28
|
) -> None:
|
29
29
|
self._params: analysis_params.AnalysisParams = params
|
30
|
-
self.circuit:
|
30
|
+
self.circuit: QuantumProgram = circuit
|
31
31
|
self.available_devices = available_devices
|
32
32
|
self.hardware_graphs = hardware_graphs
|
33
33
|
|
34
|
-
async def
|
35
|
-
self, providers:
|
34
|
+
async def _request_available_devices_async(
|
35
|
+
self, providers: list[ProviderNameEnum]
|
36
36
|
) -> None:
|
37
37
|
requested_providers = self._requested_providers_filter(providers)
|
38
38
|
if not requested_providers:
|
@@ -41,7 +41,7 @@ class AnalyzerUtilities:
|
|
41
41
|
qubit_count=self.circuit.data.width, providers=requested_providers
|
42
42
|
)
|
43
43
|
result = await ApiWrapper.call_available_devices_task(params=params)
|
44
|
-
self.available_devices.update(result.devices.
|
44
|
+
self.available_devices.update(result.devices.model_dump())
|
45
45
|
|
46
46
|
async def request_hardware_connectivity_async(
|
47
47
|
self, provider: ProviderNameEnum, device: DeviceName
|
@@ -58,7 +58,7 @@ class AnalyzerUtilities:
|
|
58
58
|
async def _device_validation_async(
|
59
59
|
self, provider: ProviderNameEnum, device: DeviceName
|
60
60
|
) -> None:
|
61
|
-
await self.
|
61
|
+
await self._request_available_devices_async(providers=[provider])
|
62
62
|
provider_lower_name = _to_lower_case(provider)
|
63
63
|
available_device_dict = self.available_devices
|
64
64
|
if available_device_dict[provider_lower_name].get(device) is False:
|
@@ -69,8 +69,8 @@ class AnalyzerUtilities:
|
|
69
69
|
)
|
70
70
|
|
71
71
|
def _requested_providers_filter(
|
72
|
-
self, providers:
|
73
|
-
) ->
|
72
|
+
self, providers: list[ProviderNameEnum]
|
73
|
+
) -> list[ProviderNameEnum]:
|
74
74
|
return list(
|
75
75
|
filter(
|
76
76
|
lambda provider: self.available_devices.get(_to_lower_case(provider))
|
@@ -81,7 +81,7 @@ class AnalyzerUtilities:
|
|
81
81
|
|
82
82
|
def _filter_devices_by_qubits_count(
|
83
83
|
self, provider: ProviderNameEnum
|
84
|
-
) ->
|
84
|
+
) -> list[DeviceName]:
|
85
85
|
device_avail_dict = self.available_devices[_to_lower_case(provider)]
|
86
86
|
return list(
|
87
87
|
filter(lambda device: device_avail_dict[device], device_avail_dict.keys())
|