classiq 0.38.0__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 +47 -32
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/api_wrapper.py +235 -97
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +10 -5
- classiq/_internals/authentication/password_manager.py +18 -6
- classiq/_internals/authentication/token_manager.py +10 -5
- classiq/_internals/client.py +94 -33
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +60 -57
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +24 -19
- classiq/analyzer/analyzer_utilities.py +10 -10
- classiq/analyzer/rb.py +15 -15
- classiq/analyzer/show_interactive_hack.py +27 -4
- 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 +165 -158
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
- classiq/applications/combinatorial_optimization/__init__.py +20 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
- 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 +48 -42
- classiq/applications/grover/__init__.py +9 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +6 -6
- 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 +1 -1
- 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 +5 -5
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +3 -6
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- 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 +20 -115
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +43 -13
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +28 -32
- classiq/interface/applications/qsvm.py +20 -29
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -121
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +25 -22
- classiq/interface/backend/quantum_backend_providers.py +69 -16
- classiq/interface/chemistry/fermionic_operator.py +30 -21
- classiq/interface/chemistry/ground_state_problem.py +28 -25
- classiq/interface/chemistry/molecule.py +14 -10
- classiq/interface/chemistry/operator.py +64 -231
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- 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/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -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/debug_info.py +86 -0
- classiq/{exceptions.py → interface/exceptions.py} +37 -9
- 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/execution_preferences.py +26 -114
- classiq/interface/executor/execution_request.py +24 -46
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +17 -14
- classiq/interface/executor/quantum_code.py +28 -24
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +11 -14
- classiq/interface/executor/result.py +83 -56
- classiq/interface/executor/vqe_result.py +10 -10
- classiq/interface/finance/function_input.py +35 -25
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +4 -4
- classiq/interface/finance/model_input.py +4 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +22 -12
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- 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 +46 -5
- classiq/interface/generator/arith/arithmetic.py +35 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
- classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
- classiq/interface/generator/arith/arithmetic_operations.py +14 -6
- 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 +3 -2
- classiq/interface/generator/arith/binary_ops.py +218 -130
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -25
- classiq/interface/generator/arith/logical_ops.py +14 -12
- classiq/interface/generator/arith/number_utils.py +12 -6
- classiq/interface/generator/arith/register_user_input.py +60 -37
- classiq/interface/generator/arith/unary_ops.py +49 -29
- 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 +3 -3
- 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 +7 -7
- classiq/interface/generator/compiler_keywords.py +5 -1
- classiq/interface/generator/complex_type.py +13 -18
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +34 -29
- 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 +21 -5
- 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 +5 -5
- classiq/interface/generator/expressions/expression.py +26 -14
- 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 +34 -8
- 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 +19 -11
- classiq/interface/generator/finance.py +2 -2
- 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 +36 -64
- classiq/interface/generator/functions/__init__.py +0 -22
- 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 +153 -20
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -25
- 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 +9 -9
- classiq/interface/generator/hardware/hardware_data.py +72 -34
- classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
- classiq/interface/generator/hartree_fock.py +13 -5
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +32 -20
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +17 -15
- classiq/interface/generator/mcx.py +24 -17
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +26 -8
- classiq/interface/generator/model/model.py +27 -190
- classiq/interface/generator/model/preferences/preferences.py +115 -41
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +15 -13
- classiq/interface/generator/oracles/oracle_abc.py +7 -7
- 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 +41 -30
- classiq/interface/generator/qsvm.py +9 -10
- classiq/interface/generator/quantum_function_call.py +88 -73
- classiq/interface/generator/quantum_program.py +41 -24
- classiq/interface/generator/range_types.py +11 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +5 -5
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -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 +4 -7
- classiq/interface/generator/state_preparation/state_preparation.py +25 -20
- 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 +7 -11
- classiq/interface/generator/ucc.py +5 -4
- classiq/interface/generator/unitary_gate.py +5 -5
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +7 -7
- classiq/interface/generator/validations/validator_functions.py +4 -4
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +29 -8
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +2 -2
- 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 -5
- classiq/interface/helpers/validation_helpers.py +3 -20
- classiq/interface/helpers/versioned_model.py +1 -4
- 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 +29 -69
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +32 -9
- 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 +29 -24
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +69 -61
- classiq/interface/model/native_function_definition.py +17 -20
- 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 +30 -18
- 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 +141 -343
- classiq/interface/model/quantum_function_declaration.py +190 -157
- classiq/interface/model/quantum_lambda_function.py +33 -32
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +177 -40
- classiq/interface/model/quantum_variable_declaration.py +3 -25
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +40 -14
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +7 -5
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +17 -21
- classiq/interface/source_reference.py +59 -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 +10 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +36 -14
- classiq/qmod/builtins/classical_functions.py +39 -43
- 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 +373 -40
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +4 -8
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +143 -101
- classiq/qmod/expression_query.py +20 -4
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +18 -6
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +16 -11
- classiq/qmod/native/pretty_printer.py +187 -97
- 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 +60 -8
- classiq/qmod/qmod_constant.py +93 -26
- classiq/qmod/qmod_parameter.py +68 -59
- classiq/qmod/qmod_variable.py +468 -155
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +269 -96
- classiq/qmod/quantum_function.py +196 -41
- 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 +147 -123
- classiq/qmod/symbolic_expr.py +27 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +98 -4
- classiq/qmod/write_qmod.py +17 -3
- classiq/synthesis.py +210 -22
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
- classiq-0.65.3.dist-info/RECORD +521 -0
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -25
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
- classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
- 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/interface/executor/aws_execution_cost.py +0 -73
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- 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/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 -1229
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- 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 -74
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/call_synthesis_data.py +0 -68
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- 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 -156
- 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 -462
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -229
- classiq/qmod/builtins/functions.py +0 -913
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -205
- 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.38.0.dist-info/RECORD +0 -454
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
- /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
- /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -1,156 +0,0 @@
|
|
1
|
-
from typing import Dict, Mapping, Set, Union
|
2
|
-
|
3
|
-
from classiq.interface.generator.function_params import PortDirection
|
4
|
-
from classiq.interface.generator.functions.core_lib_declarations.quantum_operators import (
|
5
|
-
APPLY_OPERATOR,
|
6
|
-
)
|
7
|
-
from classiq.interface.model.handle_binding import (
|
8
|
-
HandleBinding,
|
9
|
-
SlicedHandleBinding,
|
10
|
-
SubscriptHandleBinding,
|
11
|
-
)
|
12
|
-
from classiq.interface.model.port_declaration import PortDeclaration
|
13
|
-
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
14
|
-
from classiq.interface.model.quantum_lambda_function import (
|
15
|
-
QuantumLambdaFunction,
|
16
|
-
QuantumOperand,
|
17
|
-
)
|
18
|
-
from classiq.interface.model.quantum_statement import QuantumOperation
|
19
|
-
from classiq.interface.model.validation_handle import HandleState, ValidationHandle
|
20
|
-
from classiq.interface.model.validations.handle_validation_base import (
|
21
|
-
HandleValidationBase,
|
22
|
-
)
|
23
|
-
from classiq.interface.model.variable_declaration_statement import (
|
24
|
-
VariableDeclarationStatement,
|
25
|
-
)
|
26
|
-
from classiq.interface.model.within_apply_operation import WithinApplyOperation
|
27
|
-
|
28
|
-
from classiq.exceptions import ClassiqValueError
|
29
|
-
|
30
|
-
|
31
|
-
def _initialize_handles_to_state(
|
32
|
-
port_declarations: Mapping[str, PortDeclaration],
|
33
|
-
) -> Dict[str, ValidationHandle]:
|
34
|
-
handles_to_state: Dict[str, ValidationHandle] = dict()
|
35
|
-
|
36
|
-
for port_decl in port_declarations.values():
|
37
|
-
handles_to_state[port_decl.name] = ValidationHandle(
|
38
|
-
initial_state=(
|
39
|
-
HandleState.INITIALIZED
|
40
|
-
if port_decl.direction.includes_port_direction(PortDirection.Input)
|
41
|
-
else HandleState.UNINITIALIZED
|
42
|
-
)
|
43
|
-
)
|
44
|
-
|
45
|
-
return handles_to_state
|
46
|
-
|
47
|
-
|
48
|
-
class HandleValidator(HandleValidationBase):
|
49
|
-
def __init__(
|
50
|
-
self,
|
51
|
-
port_declarations: Mapping[str, PortDeclaration],
|
52
|
-
) -> None:
|
53
|
-
super().__init__(port_declarations)
|
54
|
-
self._port_declarations = port_declarations.values()
|
55
|
-
self._handles_to_state = _initialize_handles_to_state(port_declarations)
|
56
|
-
|
57
|
-
@property
|
58
|
-
def _validation_handles_state(self) -> Mapping[str, ValidationHandle]:
|
59
|
-
return self._handles_to_state
|
60
|
-
|
61
|
-
def handle_operation(self, op: QuantumOperation) -> None:
|
62
|
-
if isinstance(op, QuantumFunctionCall) and op.function == APPLY_OPERATOR.name:
|
63
|
-
self._handle_apply(op.operands[APPLY_OPERATOR.operand_names[0]])
|
64
|
-
elif isinstance(op, WithinApplyOperation):
|
65
|
-
self._handle_apply(op.action)
|
66
|
-
self._handle_inputs(op.wiring_inputs)
|
67
|
-
self._handle_outputs(op.wiring_outputs)
|
68
|
-
self._handle_inouts(op.wiring_inouts)
|
69
|
-
|
70
|
-
def handle_variable_declaration(
|
71
|
-
self, declaration: VariableDeclarationStatement
|
72
|
-
) -> None:
|
73
|
-
handle_wiring_state = self._handles_to_state.get(declaration.name)
|
74
|
-
if handle_wiring_state is not None:
|
75
|
-
handle_wiring_state.append_error(
|
76
|
-
f"Trying to declare a variable of the same name as previously declared variable {declaration.name}"
|
77
|
-
)
|
78
|
-
return
|
79
|
-
|
80
|
-
self._handles_to_state[declaration.name] = ValidationHandle(
|
81
|
-
HandleState.UNINITIALIZED
|
82
|
-
)
|
83
|
-
|
84
|
-
def _handle_inputs(self, inputs: Mapping[str, HandleBinding]) -> None:
|
85
|
-
for handle_binding in inputs.values():
|
86
|
-
handle_wiring_state = self._handles_to_state[handle_binding.name]
|
87
|
-
if handle_wiring_state.state is not HandleState.INITIALIZED:
|
88
|
-
handle_wiring_state.append_error(
|
89
|
-
f"Trying to access handle {handle_binding.name!r} as input but it is in incorrect state"
|
90
|
-
)
|
91
|
-
continue
|
92
|
-
|
93
|
-
handle_wiring_state.uninitialize()
|
94
|
-
|
95
|
-
def _handle_outputs(self, outputs: Mapping[str, HandleBinding]) -> None:
|
96
|
-
for handle_binding in outputs.values():
|
97
|
-
handle_wiring_state = self._handles_to_state[handle_binding.name]
|
98
|
-
|
99
|
-
if handle_wiring_state.state is not HandleState.UNINITIALIZED:
|
100
|
-
handle_wiring_state.append_error(
|
101
|
-
f"Trying to access handle {handle_binding.name!r} as output but it is in incorrect state"
|
102
|
-
)
|
103
|
-
continue
|
104
|
-
|
105
|
-
handle_wiring_state.initialize()
|
106
|
-
|
107
|
-
def _handle_inouts(
|
108
|
-
self,
|
109
|
-
inouts: Mapping[
|
110
|
-
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
111
|
-
],
|
112
|
-
) -> None:
|
113
|
-
sliced_handles = set()
|
114
|
-
whole_handles = set()
|
115
|
-
|
116
|
-
for handle_binding in inouts.values():
|
117
|
-
handle_wiring_state = self._handles_to_state[handle_binding.name]
|
118
|
-
|
119
|
-
if handle_wiring_state.state is not HandleState.INITIALIZED:
|
120
|
-
handle_wiring_state.append_error(
|
121
|
-
f"Trying to access handle {handle_binding.name!r} as inout but it is in incorrect state"
|
122
|
-
)
|
123
|
-
|
124
|
-
if isinstance(
|
125
|
-
handle_binding, (SlicedHandleBinding, SubscriptHandleBinding)
|
126
|
-
):
|
127
|
-
sliced_handles.add(handle_binding.name)
|
128
|
-
else:
|
129
|
-
whole_handles.add(handle_binding.name)
|
130
|
-
|
131
|
-
for handle in sliced_handles & whole_handles:
|
132
|
-
self._handles_to_state[handle].append_error(
|
133
|
-
f"Invalid use of inout handle {handle!r}, used both in slice or subscript and whole"
|
134
|
-
)
|
135
|
-
|
136
|
-
def _handle_apply(self, operand: QuantumOperand) -> None:
|
137
|
-
if not isinstance(operand, QuantumLambdaFunction):
|
138
|
-
return
|
139
|
-
local_variables: Set[str] = set()
|
140
|
-
output_capturing_variables: Set[str] = set()
|
141
|
-
for statement in operand.body:
|
142
|
-
if isinstance(statement, VariableDeclarationStatement):
|
143
|
-
local_variables.add(statement.name)
|
144
|
-
elif isinstance(statement, QuantumOperation):
|
145
|
-
for handle in statement.wiring_outputs.values():
|
146
|
-
if (
|
147
|
-
handle.name in local_variables
|
148
|
-
or handle.name in output_capturing_variables
|
149
|
-
):
|
150
|
-
continue
|
151
|
-
output_capturing_variables.add(handle.name)
|
152
|
-
self._handles_to_state[handle.name].initialize()
|
153
|
-
else:
|
154
|
-
raise ClassiqValueError(
|
155
|
-
f"Unknown statement type {type(statement).__name__}"
|
156
|
-
)
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import typing
|
2
|
-
from collections import Counter
|
3
|
-
|
4
|
-
|
5
|
-
class PortToWireNameGenerator:
|
6
|
-
def __init__(self) -> None:
|
7
|
-
self._name_counter: typing.Counter[str] = Counter()
|
8
|
-
|
9
|
-
def get(self, port_name: str) -> str:
|
10
|
-
counter = self._name_counter[port_name]
|
11
|
-
self._name_counter[port_name] += 1
|
12
|
-
return f"{port_name}_{counter}"
|
classiq/model/__init__.py
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
|
-
from classiq.interface.generator.model import * # noqa: F403
|
4
|
-
from classiq.interface.generator.model import __all__ as _model_all
|
5
|
-
|
6
|
-
from classiq.model.composite_function_generator import FunctionGenerator
|
7
|
-
from classiq.model.model import Model
|
8
|
-
|
9
|
-
__all__ = ["FunctionGenerator", "Model"]
|
10
|
-
__all__.extend(_model_all)
|
11
|
-
|
12
|
-
|
13
|
-
def __dir__() -> List[str]:
|
14
|
-
return __all__
|
@@ -1,33 +0,0 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
|
-
from classiq.interface.generator.function_params import PortDirection
|
4
|
-
from classiq.interface.generator.functions import SynthesisNativeFunctionDefinition
|
5
|
-
from classiq.interface.generator.quantum_function_call import (
|
6
|
-
SynthesisQuantumFunctionCall,
|
7
|
-
)
|
8
|
-
|
9
|
-
from classiq.model import function_handler
|
10
|
-
from classiq.quantum_functions.function_library import FunctionLibrary
|
11
|
-
|
12
|
-
|
13
|
-
class FunctionGenerator(function_handler.FunctionHandler):
|
14
|
-
def __init__(self, function_name: str) -> None:
|
15
|
-
super().__init__()
|
16
|
-
self._name = function_name
|
17
|
-
self._logic_flow_list: List[SynthesisQuantumFunctionCall] = list()
|
18
|
-
|
19
|
-
@property
|
20
|
-
def _body(self) -> List[SynthesisQuantumFunctionCall]:
|
21
|
-
return self._logic_flow_list
|
22
|
-
|
23
|
-
def to_function_definition(self) -> SynthesisNativeFunctionDefinition:
|
24
|
-
return SynthesisNativeFunctionDefinition(
|
25
|
-
name=self._name,
|
26
|
-
body=self._body,
|
27
|
-
port_declarations=self._port_declarations,
|
28
|
-
input_ports_wiring=self._external_port_wiring[PortDirection.Input],
|
29
|
-
output_ports_wiring=self._external_port_wiring[PortDirection.Output],
|
30
|
-
)
|
31
|
-
|
32
|
-
def create_library(self) -> None:
|
33
|
-
self.include_library(FunctionLibrary())
|
@@ -1,462 +0,0 @@
|
|
1
|
-
import abc
|
2
|
-
import collections.abc
|
3
|
-
import functools
|
4
|
-
from typing import (
|
5
|
-
Any,
|
6
|
-
Callable,
|
7
|
-
Collection,
|
8
|
-
Dict,
|
9
|
-
Iterable,
|
10
|
-
List,
|
11
|
-
Mapping,
|
12
|
-
Optional,
|
13
|
-
Tuple,
|
14
|
-
Union,
|
15
|
-
cast,
|
16
|
-
)
|
17
|
-
|
18
|
-
from classiq.interface.generator import function_param_list, function_params
|
19
|
-
from classiq.interface.generator.control_state import ControlState
|
20
|
-
from classiq.interface.generator.function_params import IOName, PortDirection
|
21
|
-
from classiq.interface.generator.functions.port_declaration import (
|
22
|
-
PortDeclarationDirection,
|
23
|
-
SynthesisPortDeclaration,
|
24
|
-
)
|
25
|
-
from classiq.interface.generator.identity import Identity
|
26
|
-
from classiq.interface.generator.quantum_function_call import (
|
27
|
-
SynthesisQuantumFunctionCall,
|
28
|
-
WireDict,
|
29
|
-
)
|
30
|
-
from classiq.interface.generator.slice_parsing_utils import parse_io_slicing
|
31
|
-
from classiq.interface.generator.user_defined_function_params import CustomFunction
|
32
|
-
|
33
|
-
from classiq.exceptions import ClassiqValueError, ClassiqWiringError
|
34
|
-
from classiq.model import logic_flow_change_handler
|
35
|
-
from classiq.model.logic_flow import LogicFlowBuilder
|
36
|
-
from classiq.quantum_functions.function_library import (
|
37
|
-
FunctionLibrary,
|
38
|
-
QuantumFunction,
|
39
|
-
SynthesisQuantumFunctionDeclaration,
|
40
|
-
)
|
41
|
-
from classiq.quantum_register import QReg, QRegGenericAlias
|
42
|
-
|
43
|
-
SupportedInputArgs = Union[
|
44
|
-
Mapping[IOName, QReg],
|
45
|
-
Collection[QReg],
|
46
|
-
QReg,
|
47
|
-
]
|
48
|
-
|
49
|
-
_SAME_INPUT_NAME_ERROR_MSG: str = "Cannot create multiple inputs with the same name"
|
50
|
-
_INPUT_AS_OUTPUT_ERROR_MSG: str = "Can't connect input directly to output"
|
51
|
-
ILLEGAL_INPUT_OR_SLICING_ERROR_MSG: str = "is not a valid input name/slice"
|
52
|
-
ILLEGAL_OUTPUT_ERROR_MSG: str = "Illegal output provided"
|
53
|
-
|
54
|
-
ASSIGNED = "_assigned_"
|
55
|
-
|
56
|
-
|
57
|
-
def _get_identity_call_name(name: str, io: PortDirection) -> str:
|
58
|
-
return f"{name}_{io.value}_Identity"
|
59
|
-
|
60
|
-
|
61
|
-
class FunctionHandler(abc.ABC):
|
62
|
-
def __init__(self) -> None:
|
63
|
-
self._function_library: Optional[FunctionLibrary] = None
|
64
|
-
self._port_declarations: Dict[IOName, SynthesisPortDeclaration] = dict()
|
65
|
-
self._external_port_wiring: Dict[PortDirection, WireDict] = {
|
66
|
-
PortDirection.Input: dict(),
|
67
|
-
PortDirection.Output: dict(),
|
68
|
-
}
|
69
|
-
self._generated_qregs: Dict[IOName, QReg] = dict()
|
70
|
-
self._logic_flow_builder: LogicFlowBuilder = LogicFlowBuilder()
|
71
|
-
|
72
|
-
@property
|
73
|
-
def input_wires(self) -> WireDict:
|
74
|
-
return self._external_port_wiring[PortDirection.Input]
|
75
|
-
|
76
|
-
@property
|
77
|
-
def output_wires(self) -> WireDict:
|
78
|
-
return self._external_port_wiring[PortDirection.Output]
|
79
|
-
|
80
|
-
def _verify_unique_inputs(self, input_names: Iterable[IOName]) -> None:
|
81
|
-
input_port_declarations = {
|
82
|
-
name: port_declaration
|
83
|
-
for name, port_declaration in self._port_declarations.items()
|
84
|
-
if port_declaration.direction.is_input
|
85
|
-
}
|
86
|
-
if not input_port_declarations.keys().isdisjoint(input_names):
|
87
|
-
raise ClassiqWiringError(_SAME_INPUT_NAME_ERROR_MSG)
|
88
|
-
|
89
|
-
def _verify_no_inputs_as_outputs(self, output_qregs: Iterable[QReg]) -> None:
|
90
|
-
for qreg in output_qregs:
|
91
|
-
if any(
|
92
|
-
qreg.isoverlapping(gen_qreg)
|
93
|
-
for gen_qreg in self._generated_qregs.values()
|
94
|
-
):
|
95
|
-
raise ClassiqWiringError(f"{_INPUT_AS_OUTPUT_ERROR_MSG} {qreg}")
|
96
|
-
|
97
|
-
@staticmethod
|
98
|
-
def _parse_control_states(
|
99
|
-
control_states: Optional[Union[ControlState, Iterable[ControlState]]] = None
|
100
|
-
) -> List[ControlState]:
|
101
|
-
if control_states is None:
|
102
|
-
return list()
|
103
|
-
elif isinstance(control_states, ControlState):
|
104
|
-
return [control_states]
|
105
|
-
return list(control_states)
|
106
|
-
|
107
|
-
def create_inputs(
|
108
|
-
self,
|
109
|
-
inputs: Mapping[IOName, QRegGenericAlias],
|
110
|
-
) -> Dict[IOName, QReg]:
|
111
|
-
self._verify_unique_inputs(inputs.keys())
|
112
|
-
qregs_dict = {
|
113
|
-
name: self._create_input_with_identity(name, qreg_type)
|
114
|
-
for name, qreg_type in inputs.items()
|
115
|
-
}
|
116
|
-
self._generated_qregs.update(qregs_dict)
|
117
|
-
return qregs_dict
|
118
|
-
|
119
|
-
def _create_input_with_identity(
|
120
|
-
self, name: IOName, qreg_type: QRegGenericAlias
|
121
|
-
) -> QReg:
|
122
|
-
qreg = qreg_type()
|
123
|
-
self._handle_io_with_identity(PortDirection.Input, name, qreg)
|
124
|
-
return qreg
|
125
|
-
|
126
|
-
def set_outputs(self, outputs: Mapping[IOName, QReg]) -> None:
|
127
|
-
for name, qreg in outputs.items():
|
128
|
-
self._set_output_with_identity(name, qreg)
|
129
|
-
|
130
|
-
def _set_output_with_identity(self, name: IOName, qreg: QReg) -> None:
|
131
|
-
self._handle_io_with_identity(PortDirection.Output, name, qreg)
|
132
|
-
|
133
|
-
def _handle_io_with_identity(
|
134
|
-
self, port_direction: PortDirection, name: IOName, qreg: QReg
|
135
|
-
) -> None:
|
136
|
-
# We need to add an Identity call on each input/output of the logic flow,
|
137
|
-
# since function input/output pins don't support "pin slicing".
|
138
|
-
# (Which means we cannot use QRegs in the wiring directly - because it gets
|
139
|
-
# decomposed into 1 bit wirings).
|
140
|
-
# Adding the identity also indirectly adds support for slicing on IOs
|
141
|
-
# (via the QReg slicing).
|
142
|
-
rui = qreg.to_register_user_input(name)
|
143
|
-
identity_call = SynthesisQuantumFunctionCall(
|
144
|
-
name=_get_identity_call_name(name, port_direction),
|
145
|
-
function_params=Identity(arguments=[rui]),
|
146
|
-
)
|
147
|
-
self._body.append(identity_call)
|
148
|
-
wire_name = logic_flow_change_handler.handle_io_connection(
|
149
|
-
port_direction, identity_call, name
|
150
|
-
)
|
151
|
-
if port_direction == PortDirection.Input:
|
152
|
-
self._logic_flow_builder.connect_func_call_to_qreg(
|
153
|
-
identity_call, name, qreg
|
154
|
-
)
|
155
|
-
else:
|
156
|
-
self._logic_flow_builder.connect_qreg_to_func_call(
|
157
|
-
qreg, name, identity_call
|
158
|
-
)
|
159
|
-
declaration_direction = PortDeclarationDirection.from_port_direction(
|
160
|
-
port_direction
|
161
|
-
)
|
162
|
-
if (
|
163
|
-
name in self._port_declarations
|
164
|
-
and self._port_declarations[name].direction != declaration_direction
|
165
|
-
):
|
166
|
-
declaration_direction = PortDeclarationDirection.Inout
|
167
|
-
self._port_declarations[name] = SynthesisPortDeclaration(
|
168
|
-
name=name,
|
169
|
-
size=rui.size,
|
170
|
-
direction=declaration_direction,
|
171
|
-
)
|
172
|
-
external_port_wiring_dict = dict(self._external_port_wiring[port_direction])
|
173
|
-
external_port_wiring_dict[name] = wire_name
|
174
|
-
self._external_port_wiring[port_direction] = external_port_wiring_dict
|
175
|
-
|
176
|
-
def apply(
|
177
|
-
self,
|
178
|
-
function_name: Union[
|
179
|
-
str,
|
180
|
-
SynthesisQuantumFunctionDeclaration,
|
181
|
-
QuantumFunction,
|
182
|
-
],
|
183
|
-
in_wires: Optional[SupportedInputArgs] = None,
|
184
|
-
out_wires: Optional[SupportedInputArgs] = None,
|
185
|
-
is_inverse: bool = False,
|
186
|
-
strict_zero_ios: bool = True,
|
187
|
-
release_by_inverse: bool = False,
|
188
|
-
control_states: Optional[Union[ControlState, Iterable[ControlState]]] = None,
|
189
|
-
should_control: bool = True,
|
190
|
-
power: int = 1,
|
191
|
-
call_name: Optional[str] = None,
|
192
|
-
) -> Dict[IOName, QReg]:
|
193
|
-
# if there's no function library, create one
|
194
|
-
if self._function_library is None:
|
195
|
-
self.create_library()
|
196
|
-
|
197
|
-
if isinstance(function_name, SynthesisQuantumFunctionDeclaration):
|
198
|
-
function_data = function_name
|
199
|
-
elif isinstance(function_name, QuantumFunction):
|
200
|
-
function_data = function_name.function_data
|
201
|
-
else:
|
202
|
-
function_data = None
|
203
|
-
|
204
|
-
if function_data:
|
205
|
-
if function_data.name not in self._function_library.function_dict: # type: ignore[union-attr]
|
206
|
-
self._function_library.add_function(function_data) # type: ignore[union-attr]
|
207
|
-
|
208
|
-
function_name = function_data.name
|
209
|
-
|
210
|
-
function_name = cast(str, function_name)
|
211
|
-
return self._add_function_call(
|
212
|
-
function_name,
|
213
|
-
self._function_library.get_function(function_name), # type: ignore[union-attr]
|
214
|
-
in_wires=in_wires,
|
215
|
-
out_wires=out_wires,
|
216
|
-
is_inverse=is_inverse,
|
217
|
-
strict_zero_ios=strict_zero_ios,
|
218
|
-
release_by_inverse=release_by_inverse,
|
219
|
-
control_states=control_states,
|
220
|
-
should_control=should_control,
|
221
|
-
power=power,
|
222
|
-
call_name=call_name,
|
223
|
-
)
|
224
|
-
|
225
|
-
def release_qregs(self, qregs: Union[QReg, Collection[QReg]]) -> None:
|
226
|
-
if isinstance(qregs, QReg):
|
227
|
-
qregs = [qregs]
|
228
|
-
for qreg in qregs:
|
229
|
-
self._logic_flow_builder.connect_qreg_to_zero(qreg)
|
230
|
-
|
231
|
-
def _add_function_call(
|
232
|
-
self,
|
233
|
-
function: str,
|
234
|
-
params: function_params.FunctionParams,
|
235
|
-
control_states: Optional[Union[ControlState, Iterable[ControlState]]] = None,
|
236
|
-
in_wires: Optional[SupportedInputArgs] = None,
|
237
|
-
out_wires: Optional[SupportedInputArgs] = None,
|
238
|
-
is_inverse: bool = False,
|
239
|
-
release_by_inverse: bool = False,
|
240
|
-
should_control: bool = True,
|
241
|
-
power: int = 1,
|
242
|
-
call_name: Optional[str] = None,
|
243
|
-
strict_zero_ios: bool = True,
|
244
|
-
) -> Dict[IOName, QReg]:
|
245
|
-
if function != type(params).__name__ and not isinstance(params, CustomFunction):
|
246
|
-
raise ClassiqValueError(
|
247
|
-
"The FunctionParams type does not match function name"
|
248
|
-
)
|
249
|
-
|
250
|
-
if (
|
251
|
-
isinstance(params, CustomFunction)
|
252
|
-
and self._function_library
|
253
|
-
and function not in self._function_library.function_dict
|
254
|
-
):
|
255
|
-
raise ClassiqValueError(
|
256
|
-
"QuantumFunctionCall: The function is not found in included library."
|
257
|
-
)
|
258
|
-
|
259
|
-
call = SynthesisQuantumFunctionCall(
|
260
|
-
function=function,
|
261
|
-
function_params=params,
|
262
|
-
is_inverse=is_inverse,
|
263
|
-
release_by_inverse=release_by_inverse,
|
264
|
-
strict_zero_ios=strict_zero_ios,
|
265
|
-
control_states=self._parse_control_states(control_states),
|
266
|
-
should_control=should_control,
|
267
|
-
power=power,
|
268
|
-
name=call_name,
|
269
|
-
)
|
270
|
-
|
271
|
-
if in_wires is not None:
|
272
|
-
self._connect_in_qregs(call=call, in_wires=in_wires)
|
273
|
-
|
274
|
-
self._body.append(call)
|
275
|
-
|
276
|
-
return self._connect_out_qregs(call=call, out_wires=out_wires or {})
|
277
|
-
|
278
|
-
def _connect_in_qregs(
|
279
|
-
self,
|
280
|
-
call: SynthesisQuantumFunctionCall,
|
281
|
-
in_wires: SupportedInputArgs,
|
282
|
-
) -> None:
|
283
|
-
if isinstance(in_wires, dict):
|
284
|
-
self._connect_named_in_qregs(call=call, in_wires=in_wires)
|
285
|
-
elif isinstance(in_wires, QReg):
|
286
|
-
self._connect_unnamed_in_qregs(call=call, in_wires=[in_wires])
|
287
|
-
elif isinstance(in_wires, collections.abc.Collection):
|
288
|
-
self._connect_unnamed_in_qregs(
|
289
|
-
# mypy doesn't recognize that `dict` wouldn't reach this point
|
290
|
-
call=call,
|
291
|
-
in_wires=in_wires, # type: ignore[arg-type]
|
292
|
-
)
|
293
|
-
else:
|
294
|
-
raise ClassiqWiringError(
|
295
|
-
f"Invalid in_wires type: {type(in_wires).__name__}"
|
296
|
-
)
|
297
|
-
|
298
|
-
def _connect_unnamed_in_qregs(
|
299
|
-
self,
|
300
|
-
call: SynthesisQuantumFunctionCall,
|
301
|
-
in_wires: Collection[QReg],
|
302
|
-
) -> None:
|
303
|
-
call_inputs = call.function_params.inputs_full(call.strict_zero_ios).keys()
|
304
|
-
self._connect_named_in_qregs(call, dict(zip(call_inputs, in_wires)))
|
305
|
-
|
306
|
-
def _connect_named_in_qregs(
|
307
|
-
self,
|
308
|
-
call: SynthesisQuantumFunctionCall,
|
309
|
-
in_wires: Dict[IOName, QReg],
|
310
|
-
) -> None:
|
311
|
-
for input_name, in_qreg in in_wires.items():
|
312
|
-
pin_name, pin_indices = self._get_pin_name_and_indices(input_name, call)
|
313
|
-
if len(in_qreg) != len(pin_indices):
|
314
|
-
raise ClassiqWiringError(
|
315
|
-
f"Incorrect size of input QReg: expected {len(pin_indices)}, actual {len(in_qreg)}"
|
316
|
-
)
|
317
|
-
self._logic_flow_builder.connect_qreg_to_func_call(
|
318
|
-
in_qreg, pin_name, call, pin_indices
|
319
|
-
)
|
320
|
-
|
321
|
-
@staticmethod
|
322
|
-
def _get_pin_name_and_indices(
|
323
|
-
input_name: IOName,
|
324
|
-
call: SynthesisQuantumFunctionCall,
|
325
|
-
) -> Tuple[IOName, range]:
|
326
|
-
try:
|
327
|
-
name, slicing = parse_io_slicing(input_name)
|
328
|
-
except (AssertionError, ValueError) as e:
|
329
|
-
raise ClassiqWiringError(
|
330
|
-
f"{input_name} {ILLEGAL_INPUT_OR_SLICING_ERROR_MSG}"
|
331
|
-
) from e
|
332
|
-
pin_info = call.input_regs_dict.get(name)
|
333
|
-
if pin_info is None:
|
334
|
-
raise ClassiqWiringError(
|
335
|
-
f"No register size information on input pin {name}"
|
336
|
-
)
|
337
|
-
indices = range(pin_info.size)[slicing]
|
338
|
-
return name, indices
|
339
|
-
|
340
|
-
def _connect_out_qregs(
|
341
|
-
self,
|
342
|
-
call: SynthesisQuantumFunctionCall,
|
343
|
-
out_wires: SupportedInputArgs,
|
344
|
-
) -> Dict[IOName, QReg]:
|
345
|
-
if isinstance(out_wires, dict):
|
346
|
-
return self._connect_named_out_qregs(call, out_wires)
|
347
|
-
elif isinstance(out_wires, QReg):
|
348
|
-
return self._connect_unnamed_out_qregs(call, [out_wires])
|
349
|
-
elif isinstance(out_wires, collections.abc.Collection):
|
350
|
-
return self._connect_unnamed_out_qregs(
|
351
|
-
# mypy doesn't recognize that `dict` wouldn't reach this point
|
352
|
-
call,
|
353
|
-
out_wires, # type: ignore[arg-type]
|
354
|
-
)
|
355
|
-
else:
|
356
|
-
raise ClassiqWiringError(
|
357
|
-
f"Invalid in_wires type: {type(out_wires).__name__}"
|
358
|
-
)
|
359
|
-
|
360
|
-
def _connect_unnamed_out_qregs(
|
361
|
-
self,
|
362
|
-
call: SynthesisQuantumFunctionCall,
|
363
|
-
out_wires: Collection[QReg],
|
364
|
-
) -> Dict[IOName, QReg]:
|
365
|
-
call_outputs = call.function_params.outputs.keys()
|
366
|
-
return self._connect_named_out_qregs(call, dict(zip(call_outputs, out_wires)))
|
367
|
-
|
368
|
-
def _connect_named_out_qregs(
|
369
|
-
self,
|
370
|
-
call: SynthesisQuantumFunctionCall,
|
371
|
-
out_wires: Mapping[IOName, QReg],
|
372
|
-
) -> Dict[IOName, QReg]:
|
373
|
-
if not all(output_name in call.output_regs_dict for output_name in out_wires):
|
374
|
-
raise ClassiqWiringError(ILLEGAL_OUTPUT_ERROR_MSG)
|
375
|
-
output_dict = {}
|
376
|
-
for output_name, reg_user_input in call.output_regs_dict.items():
|
377
|
-
if reg_user_input is None:
|
378
|
-
raise ClassiqValueError(
|
379
|
-
f"No output register information for {output_name}"
|
380
|
-
)
|
381
|
-
qreg = out_wires.get(output_name) or QReg.from_arithmetic_info(
|
382
|
-
reg_user_input
|
383
|
-
)
|
384
|
-
self._logic_flow_builder.connect_func_call_to_qreg(call, output_name, qreg)
|
385
|
-
output_dict[output_name] = qreg
|
386
|
-
return output_dict
|
387
|
-
|
388
|
-
def __getattr__(self, item: str) -> Callable[..., Any]:
|
389
|
-
# This is added due to problematic behaviour in deepcopy.
|
390
|
-
# deepcopy approaches __getattr__ before __init__ is called,
|
391
|
-
# and therefore self._function_library doesn't exist.
|
392
|
-
# Thus, we treat _function_library differently.
|
393
|
-
|
394
|
-
if item == "_function_library":
|
395
|
-
raise AttributeError(
|
396
|
-
f"{self.__class__.__name__!r} has no attribute {item!r}"
|
397
|
-
)
|
398
|
-
|
399
|
-
is_builtin_function_name = any(
|
400
|
-
item == func.__name__
|
401
|
-
for func in function_param_list.function_param_library.param_list
|
402
|
-
)
|
403
|
-
|
404
|
-
if is_builtin_function_name:
|
405
|
-
return functools.partial(self._add_function_call, item)
|
406
|
-
|
407
|
-
is_user_function_name = (
|
408
|
-
self._function_library is not None
|
409
|
-
and item in self._function_library.function_names
|
410
|
-
)
|
411
|
-
|
412
|
-
if is_user_function_name:
|
413
|
-
return functools.partial(self.apply, item)
|
414
|
-
|
415
|
-
if (
|
416
|
-
self._function_library is not None
|
417
|
-
and item in self._function_library.function_factory_names
|
418
|
-
):
|
419
|
-
return functools.partial(
|
420
|
-
self._function_library.get_function_factory(item),
|
421
|
-
add_method=functools.partial(
|
422
|
-
self._function_library.add_function,
|
423
|
-
override_existing_functions=True,
|
424
|
-
),
|
425
|
-
apply_method=self.apply,
|
426
|
-
)
|
427
|
-
|
428
|
-
raise AttributeError(f"{self.__class__.__name__!r} has no attribute {item!r}")
|
429
|
-
|
430
|
-
def __dir__(self) -> List[str]:
|
431
|
-
builtin_func_name = [
|
432
|
-
func.__name__
|
433
|
-
for func in function_param_list.function_param_library.param_list
|
434
|
-
]
|
435
|
-
user_func_names = (
|
436
|
-
list(self._function_library.function_names)
|
437
|
-
if self._function_library is not None
|
438
|
-
else list()
|
439
|
-
)
|
440
|
-
return list(super().__dir__()) + builtin_func_name + user_func_names
|
441
|
-
|
442
|
-
def include_library(self, library: FunctionLibrary) -> None:
|
443
|
-
"""Includes a function library.
|
444
|
-
|
445
|
-
Args:
|
446
|
-
library (FunctionLibrary): The function library.
|
447
|
-
"""
|
448
|
-
if self._function_library is not None:
|
449
|
-
raise ClassiqValueError("Another function library is already included.")
|
450
|
-
|
451
|
-
self._function_library = library
|
452
|
-
|
453
|
-
@property
|
454
|
-
@abc.abstractmethod
|
455
|
-
def _body(
|
456
|
-
self,
|
457
|
-
) -> List[SynthesisQuantumFunctionCall]:
|
458
|
-
pass
|
459
|
-
|
460
|
-
@abc.abstractmethod
|
461
|
-
def create_library(self) -> None:
|
462
|
-
pass
|