classiq 0.37.1__py3-none-any.whl → 0.65.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +49 -34
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +241 -95
- classiq/_internals/async_utils.py +2 -77
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +18 -8
- classiq/_internals/authentication/password_manager.py +40 -13
- classiq/_internals/authentication/token_manager.py +11 -6
- classiq/_internals/client.py +106 -37
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +56 -50
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +50 -47
- classiq/analyzer/analyzer_utilities.py +15 -15
- classiq/analyzer/rb.py +19 -20
- classiq/analyzer/show_interactive_hack.py +30 -7
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/__init__.py +3 -12
- classiq/applications/chemistry/__init__.py +14 -10
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
- classiq/applications/combinatorial_helpers/memory.py +75 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
- classiq/applications/combinatorial_optimization/__init__.py +24 -5
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +4 -5
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
- classiq/applications/grover/__init__.py +9 -0
- classiq/applications/grover/grover_model_constructor.py +157 -0
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +8 -8
- classiq/applications/qnn/datasets/__init__.py +9 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +30 -10
- classiq/applications/qnn/torch_utils.py +4 -3
- classiq/applications/qnn/types.py +7 -7
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +4 -10
- classiq/applications/qsvm/qsvm_data_generation.py +5 -8
- classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
- classiq/execution/__init__.py +8 -3
- classiq/execution/all_hardware_devices.py +11 -0
- classiq/execution/execution_session.py +400 -0
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +197 -25
- classiq/execution/qnn.py +79 -0
- classiq/executor.py +23 -117
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +49 -16
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +36 -32
- classiq/interface/applications/qsvm.py +28 -25
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -119
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +27 -22
- classiq/interface/backend/quantum_backend_providers.py +70 -16
- classiq/interface/chemistry/fermionic_operator.py +43 -32
- classiq/interface/chemistry/ground_state_problem.py +42 -24
- classiq/interface/chemistry/molecule.py +20 -14
- classiq/interface/chemistry/operator.py +75 -236
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +86 -0
- classiq/interface/exceptions.py +201 -0
- classiq/interface/execution/iqcc.py +19 -0
- classiq/interface/execution/jobs.py +15 -12
- classiq/interface/execution/primitives.py +18 -0
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +26 -143
- classiq/interface/executor/execution_request.py +36 -56
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +34 -22
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
- classiq/interface/executor/quantum_instruction_set.py +3 -2
- classiq/interface/executor/register_initialization.py +12 -17
- classiq/interface/executor/result.py +122 -64
- classiq/interface/executor/vqe_result.py +11 -11
- classiq/interface/finance/function_input.py +42 -19
- classiq/interface/finance/gaussian_model_input.py +7 -5
- classiq/interface/finance/log_normal_model_input.py +6 -4
- classiq/interface/finance/model_input.py +6 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +27 -14
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
- classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +48 -69
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
- classiq/interface/generator/arith/argument_utils.py +57 -6
- classiq/interface/generator/arith/arithmetic.py +37 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
- classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
- classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
- classiq/interface/generator/arith/arithmetic_operations.py +19 -16
- classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
- classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
- classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
- classiq/interface/generator/arith/binary_ops.py +375 -139
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -23
- classiq/interface/generator/arith/logical_ops.py +16 -12
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +44 -48
- classiq/interface/generator/arith/register_user_input.py +70 -27
- classiq/interface/generator/arith/unary_ops.py +57 -46
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/builtin_api_builder.py +2 -9
- classiq/interface/generator/chemistry_function_params.py +5 -5
- classiq/interface/generator/circuit_code/circuit_code.py +7 -7
- classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
- classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
- classiq/interface/generator/compiler_keywords.py +8 -0
- classiq/interface/generator/complex_type.py +13 -25
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +35 -28
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/custom_ansatz.py +2 -5
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
- classiq/interface/generator/expressions/enums/__init__.py +0 -10
- classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
- classiq/interface/generator/expressions/evaluated_expression.py +21 -7
- classiq/interface/generator/expressions/expression.py +27 -15
- classiq/interface/generator/expressions/expression_constants.py +9 -3
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
- classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
- classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
- classiq/interface/generator/finance.py +3 -3
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
- classiq/interface/generator/function_params.py +42 -69
- classiq/interface/generator/functions/__init__.py +0 -22
- classiq/interface/generator/functions/builtins/__init__.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
- classiq/interface/generator/functions/classical_function_declaration.py +18 -9
- classiq/interface/generator/functions/classical_type.py +47 -166
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +13 -14
- classiq/interface/generator/functions/port_declaration.py +1 -13
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +90 -0
- classiq/interface/generator/generated_circuit_data.py +155 -22
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -23
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
- classiq/interface/generator/hardware/hardware_data.py +76 -36
- classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
- classiq/interface/generator/hartree_fock.py +14 -4
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +33 -19
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +20 -16
- classiq/interface/generator/mcx.py +29 -20
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +27 -8
- classiq/interface/generator/model/model.py +32 -203
- classiq/interface/generator/model/preferences/preferences.py +118 -43
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +17 -13
- classiq/interface/generator/oracles/oracle_abc.py +9 -9
- classiq/interface/generator/partitioned_register.py +7 -7
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +47 -34
- classiq/interface/generator/qsvm.py +13 -17
- classiq/interface/generator/quantum_function_call.py +107 -87
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
- classiq/interface/generator/range_types.py +13 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +11 -6
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +16 -15
- classiq/interface/generator/state_preparation/metrics.py +5 -7
- classiq/interface/generator/state_preparation/state_preparation.py +30 -23
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
- classiq/interface/generator/transpiler_basis_gates.py +7 -3
- classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
- classiq/interface/generator/types/compilation_metadata.py +6 -0
- classiq/interface/generator/types/enum_declaration.py +54 -0
- classiq/interface/generator/types/qstruct_declaration.py +18 -0
- classiq/interface/generator/types/struct_declaration.py +15 -14
- classiq/interface/generator/ucc.py +9 -6
- classiq/interface/generator/unitary_gate.py +10 -6
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +11 -9
- classiq/interface/generator/validations/validator_functions.py +8 -6
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +31 -10
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/custom_pydantic_types.py +40 -50
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +7 -11
- classiq/interface/helpers/validation_helpers.py +4 -21
- classiq/interface/helpers/versioned_model.py +1 -1
- classiq/interface/ide/ide_data.py +16 -20
- classiq/interface/ide/visual_model.py +130 -0
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +35 -6
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +44 -14
- classiq/interface/model/classical_if.py +15 -0
- classiq/interface/model/classical_parameter_declaration.py +33 -3
- classiq/interface/model/control.py +45 -0
- classiq/interface/model/handle_binding.py +298 -20
- classiq/interface/model/inplace_binary_operation.py +31 -26
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +87 -73
- classiq/interface/model/native_function_definition.py +16 -21
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +27 -9
- classiq/interface/model/power.py +14 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
- classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
- classiq/interface/model/quantum_function_call.py +146 -462
- classiq/interface/model/quantum_function_declaration.py +193 -152
- classiq/interface/model/quantum_lambda_function.py +65 -0
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +205 -67
- classiq/interface/model/quantum_variable_declaration.py +4 -26
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +58 -0
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +13 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +22 -21
- classiq/interface/source_reference.py +59 -0
- classiq/model_expansions/__init__.py +0 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
- classiq/model_expansions/capturing/__init__.py +0 -0
- classiq/model_expansions/capturing/captured_vars.py +435 -0
- classiq/model_expansions/capturing/mangling_utils.py +56 -0
- classiq/model_expansions/closure.py +171 -0
- classiq/model_expansions/debug_flag.py +3 -0
- classiq/model_expansions/evaluators/__init__.py +0 -0
- classiq/model_expansions/evaluators/arg_type_match.py +158 -0
- classiq/model_expansions/evaluators/argument_types.py +42 -0
- classiq/model_expansions/evaluators/classical_expression.py +36 -0
- classiq/model_expansions/evaluators/control.py +144 -0
- classiq/model_expansions/evaluators/parameter_types.py +226 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
- classiq/model_expansions/evaluators/type_type_match.py +90 -0
- classiq/model_expansions/expression_evaluator.py +135 -0
- classiq/model_expansions/expression_renamer.py +76 -0
- classiq/model_expansions/function_builder.py +247 -0
- classiq/model_expansions/generative_functions.py +158 -0
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +18 -0
- classiq/model_expansions/quantum_operations/__init__.py +9 -0
- classiq/model_expansions/quantum_operations/bind.py +60 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
- classiq/model_expansions/quantum_operations/classicalif.py +53 -0
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +181 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
- classiq/model_expansions/quantum_operations/repeat.py +56 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
- classiq/model_expansions/scope.py +240 -0
- classiq/model_expansions/scope_initialization.py +150 -0
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
- classiq/model_expansions/transformers/__init__.py +0 -0
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +299 -0
- classiq/model_expansions/utils/__init__.py +0 -0
- classiq/model_expansions/utils/counted_name_allocator.py +11 -0
- classiq/model_expansions/utils/handles_collector.py +33 -0
- classiq/model_expansions/visitors/__init__.py +0 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
- classiq/model_expansions/visitors/variable_references.py +144 -0
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/open_library/functions/amplitude_estimation.py +30 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
- classiq/open_library/functions/grover.py +157 -0
- classiq/open_library/functions/hea.py +115 -0
- classiq/open_library/functions/linear_pauli_rotation.py +82 -0
- classiq/open_library/functions/modular_exponentiation.py +201 -0
- classiq/open_library/functions/qaoa_penalty.py +117 -0
- classiq/open_library/functions/qft_functions.py +54 -0
- classiq/open_library/functions/qpe.py +46 -0
- classiq/open_library/functions/qsvt.py +331 -0
- classiq/open_library/functions/state_preparation.py +301 -0
- classiq/open_library/functions/swap_test.py +27 -0
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/open_library/functions/variational.py +52 -0
- classiq/qmod/__init__.py +17 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +60 -47
- classiq/qmod/builtins/classical_functions.py +44 -38
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/enums.py +208 -0
- classiq/qmod/builtins/functions/__init__.py +137 -0
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +55 -0
- classiq/qmod/builtins/functions/benchmarking.py +8 -0
- classiq/qmod/builtins/functions/chemistry.py +91 -0
- classiq/qmod/builtins/functions/exponentiation.py +105 -0
- classiq/qmod/builtins/functions/finance.py +34 -0
- classiq/qmod/builtins/functions/operators.py +16 -0
- classiq/qmod/builtins/functions/qsvm.py +24 -0
- classiq/qmod/builtins/functions/standard_gates.py +651 -0
- classiq/qmod/builtins/operations.py +379 -57
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +8 -20
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +145 -112
- classiq/qmod/expression_query.py +39 -0
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +19 -5
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +194 -0
- classiq/qmod/native/pretty_printer.py +401 -0
- classiq/qmod/pretty_print/__init__.py +7 -0
- classiq/qmod/pretty_print/expression_to_python.py +222 -0
- classiq/qmod/pretty_print/pretty_printer.py +572 -0
- classiq/qmod/python_classical_type.py +67 -0
- classiq/qmod/qfunc.py +79 -0
- classiq/qmod/qmod_constant.py +143 -0
- classiq/qmod/qmod_parameter.py +84 -53
- classiq/qmod/qmod_variable.py +497 -100
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +278 -105
- classiq/qmod/quantum_function.py +232 -48
- classiq/qmod/semantics/__init__.py +0 -0
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
- classiq/qmod/semantics/error_manager.py +88 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +384 -0
- classiq/qmod/semantics/validation/__init__.py +0 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- classiq/qmod/semantics/validation/func_call_validation.py +99 -0
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +128 -0
- classiq/qmod/symbolic.py +178 -111
- classiq/qmod/symbolic_expr.py +36 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +108 -1
- classiq/qmod/write_qmod.py +53 -0
- classiq/synthesis.py +210 -22
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
- classiq-0.65.3.dist-info/RECORD +521 -0
- {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/grover_model_constructor.py +0 -227
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/exceptions.py +0 -131
- classiq/interface/executor/aws_execution_cost.py +0 -72
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- classiq/interface/generator/functions/foreign_function_definition.py +0 -106
- classiq/interface/generator/functions/function_implementation.py +0 -103
- classiq/interface/generator/functions/native_function_definition.py +0 -153
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -42
- classiq/interface/generator/functions/register_mapping_data.py +0 -102
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -63
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -95
- classiq/interface/model/resolvers/function_call_resolver.py +0 -43
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -154
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/qmod/builtins/functions.py +0 -896
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- classiq-0.37.1.dist-info/RECORD +0 -418
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
- /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
classiq/qmod/quantum_function.py
CHANGED
@@ -1,58 +1,116 @@
|
|
1
|
+
import ast
|
1
2
|
import functools
|
2
|
-
from
|
3
|
+
from abc import abstractmethod
|
4
|
+
from collections import defaultdict
|
5
|
+
from dataclasses import is_dataclass
|
6
|
+
from enum import EnumMeta
|
7
|
+
from inspect import isclass
|
8
|
+
from typing import Any, Callable, Optional, get_origin
|
3
9
|
|
10
|
+
from classiq.interface.exceptions import ClassiqError
|
4
11
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
12
|
+
from classiq.interface.generator.functions.port_declaration import (
|
13
|
+
PortDeclarationDirection,
|
14
|
+
)
|
5
15
|
from classiq.interface.generator.model.constraints import Constraints
|
6
16
|
from classiq.interface.generator.model.preferences.preferences import Preferences
|
7
|
-
from classiq.interface.
|
8
|
-
from classiq.interface.model.
|
17
|
+
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
18
|
+
from classiq.interface.model.model import Model
|
19
|
+
from classiq.interface.model.native_function_definition import (
|
20
|
+
NativeFunctionDefinition,
|
21
|
+
)
|
9
22
|
from classiq.interface.model.quantum_function_declaration import (
|
10
|
-
|
23
|
+
NamedParamsQuantumFunctionDeclaration,
|
11
24
|
)
|
12
25
|
|
13
|
-
from classiq.exceptions import ClassiqError
|
14
26
|
from classiq.qmod.classical_function import CFunc
|
15
27
|
from classiq.qmod.declaration_inferrer import infer_func_decl
|
16
|
-
from classiq.qmod.
|
28
|
+
from classiq.qmod.generative import set_frontend_interpreter
|
29
|
+
from classiq.qmod.qmod_constant import QConstant
|
30
|
+
from classiq.qmod.qmod_parameter import CArray, CParam
|
17
31
|
from classiq.qmod.qmod_variable import QVar
|
18
32
|
from classiq.qmod.quantum_callable import QCallable, QCallableList
|
19
33
|
from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
|
20
|
-
from classiq.qmod.utilities import mangle_keyword
|
34
|
+
from classiq.qmod.utilities import mangle_keyword
|
21
35
|
|
22
36
|
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
class BaseQFunc(QExpandable):
|
38
|
+
def __init__(
|
39
|
+
self,
|
40
|
+
py_callable: Callable,
|
41
|
+
compilation_metadata: Optional[CompilationMetadata] = None,
|
42
|
+
) -> None:
|
43
|
+
super().__init__(py_callable)
|
44
|
+
self.compilation_metadata = compilation_metadata
|
26
45
|
|
46
|
+
@property
|
47
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
48
|
+
raise NotImplementedError
|
27
49
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
) -> SerializedModel:
|
35
|
-
return entry_point.create_model(
|
36
|
-
constraints, execution_preferences, preferences, classical_execution_function
|
37
|
-
).get_model()
|
50
|
+
@property
|
51
|
+
def _has_inputs(self) -> bool:
|
52
|
+
return any(
|
53
|
+
port.direction == PortDeclarationDirection.Input
|
54
|
+
for port in self.func_decl.port_declarations
|
55
|
+
)
|
38
56
|
|
57
|
+
def update_compilation_metadata(self, **kwargs: Any) -> None:
|
58
|
+
if kwargs["should_synthesize_separately"] and self._has_inputs:
|
59
|
+
raise ClassiqError("Can't synthesize separately a function with inputs")
|
60
|
+
self.compilation_metadata = self._compilation_metadata.model_copy(update=kwargs)
|
39
61
|
|
40
|
-
|
41
|
-
def
|
62
|
+
@property
|
63
|
+
def _compilation_metadata(self) -> CompilationMetadata:
|
64
|
+
if self.compilation_metadata is None:
|
65
|
+
return CompilationMetadata()
|
66
|
+
return self.compilation_metadata
|
67
|
+
|
68
|
+
@abstractmethod
|
69
|
+
def create_model(
|
70
|
+
self,
|
71
|
+
constraints: Optional[Constraints] = None,
|
72
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
73
|
+
preferences: Optional[Preferences] = None,
|
74
|
+
classical_execution_function: Optional[CFunc] = None,
|
75
|
+
) -> Model:
|
76
|
+
pass
|
77
|
+
|
78
|
+
|
79
|
+
class QFunc(BaseQFunc):
|
80
|
+
FRAME_DEPTH = 3
|
81
|
+
|
82
|
+
def __init__(
|
83
|
+
self,
|
84
|
+
py_callable: Callable,
|
85
|
+
compilation_metadata: Optional[CompilationMetadata] = None,
|
86
|
+
) -> None:
|
42
87
|
_validate_no_gen_params(py_callable.__annotations__)
|
43
|
-
super().__init__(py_callable)
|
88
|
+
super().__init__(py_callable, compilation_metadata)
|
44
89
|
functools.update_wrapper(self, py_callable)
|
90
|
+
self.compilation_metadata: Optional[CompilationMetadata] = None
|
45
91
|
|
46
92
|
@property
|
47
|
-
def
|
48
|
-
|
49
|
-
self.
|
50
|
-
|
93
|
+
def pure_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
94
|
+
if type(self.func_decl) is NamedParamsQuantumFunctionDeclaration:
|
95
|
+
return self.func_decl
|
96
|
+
return NamedParamsQuantumFunctionDeclaration(
|
97
|
+
**{
|
98
|
+
k: v
|
99
|
+
for k, v in self.func_decl.model_dump().items()
|
100
|
+
if k in NamedParamsQuantumFunctionDeclaration.model_fields
|
101
|
+
}
|
51
102
|
)
|
52
103
|
|
104
|
+
@property
|
105
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
106
|
+
name = self._py_callable.__name__
|
107
|
+
if hasattr(self._qmodule, "native_defs") and name in self._qmodule.native_defs:
|
108
|
+
return self._qmodule.native_defs[name]
|
109
|
+
return infer_func_decl(self._py_callable, qmodule=self._qmodule)
|
110
|
+
|
53
111
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
112
|
+
self.expand()
|
54
113
|
super().__call__(*args, **kwargs)
|
55
|
-
self._add_native_func_def()
|
56
114
|
|
57
115
|
def create_model(
|
58
116
|
self,
|
@@ -61,69 +119,195 @@ class QFunc(QExpandable):
|
|
61
119
|
preferences: Optional[Preferences] = None,
|
62
120
|
classical_execution_function: Optional[CFunc] = None,
|
63
121
|
) -> Model:
|
122
|
+
self._qmodule.enum_decls = dict()
|
64
123
|
self._qmodule.type_decls = dict()
|
124
|
+
self._qmodule.qstruct_decls = dict()
|
65
125
|
self._qmodule.native_defs = dict()
|
66
|
-
self.
|
67
|
-
|
126
|
+
self._qmodule.constants = dict()
|
127
|
+
self._qmodule.functions_compilation_metadata = dict()
|
128
|
+
self._qmodule.generative_functions = dict()
|
129
|
+
self._qmodule.function_dependencies = defaultdict(list)
|
130
|
+
QConstant.set_current_model(self._qmodule)
|
131
|
+
self.expand()
|
132
|
+
model_extra_settings: list[tuple[str, Any]] = [
|
68
133
|
("constraints", constraints),
|
69
134
|
("execution_preferences", execution_preferences),
|
70
135
|
("preferences", preferences),
|
71
136
|
]
|
72
|
-
classical_execution_function
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
137
|
+
if classical_execution_function is not None:
|
138
|
+
self._add_constants_from_classical_code(classical_execution_function)
|
139
|
+
model_extra_settings.append(
|
140
|
+
("classical_execution_code", classical_execution_function.code)
|
141
|
+
)
|
142
|
+
model = Model(
|
143
|
+
constants=list(self._qmodule.constants.values()),
|
78
144
|
functions=list(self._qmodule.native_defs.values()),
|
145
|
+
enums=list(self._qmodule.enum_decls.values()),
|
79
146
|
types=list(self._qmodule.type_decls.values()),
|
80
|
-
|
147
|
+
qstructs=list(self._qmodule.qstruct_decls.values()),
|
148
|
+
functions_compilation_metadata=self._qmodule.functions_compilation_metadata,
|
81
149
|
**{key: value for key, value in model_extra_settings if value},
|
82
150
|
)
|
151
|
+
if len(self._qmodule.generative_functions) > 0:
|
152
|
+
return self._create_generative_model(model)
|
153
|
+
return model
|
83
154
|
|
84
|
-
def
|
155
|
+
def _create_generative_model(self, model_stub: Model) -> Model:
|
156
|
+
from classiq.model_expansions.interpreters.frontend_generative_interpreter import (
|
157
|
+
FrontendGenerativeInterpreter,
|
158
|
+
)
|
159
|
+
from classiq.qmod.semantics.annotation.call_annotation import (
|
160
|
+
resolve_function_calls,
|
161
|
+
)
|
162
|
+
|
163
|
+
generative_functions = list(self._qmodule.generative_functions.values())
|
164
|
+
resolve_function_calls(
|
165
|
+
model_stub,
|
166
|
+
dict(model_stub.function_dict)
|
167
|
+
| {
|
168
|
+
gen_func.func_decl.name: gen_func.func_decl
|
169
|
+
for gen_func in generative_functions
|
170
|
+
},
|
171
|
+
)
|
172
|
+
interpreter = FrontendGenerativeInterpreter(model_stub, generative_functions)
|
173
|
+
set_frontend_interpreter(interpreter)
|
174
|
+
return interpreter.expand()
|
175
|
+
|
176
|
+
def expand(self) -> None:
|
85
177
|
if self.func_decl.name in self._qmodule.native_defs:
|
86
178
|
return
|
87
|
-
|
179
|
+
super().expand()
|
88
180
|
self._qmodule.native_defs[self.func_decl.name] = NativeFunctionDefinition(
|
89
|
-
**self.func_decl.
|
181
|
+
**{**self.func_decl.model_dump(), **{"body": self.body}}
|
90
182
|
)
|
183
|
+
if self.compilation_metadata is not None:
|
184
|
+
self._qmodule.functions_compilation_metadata[self.func_decl.name] = (
|
185
|
+
self.compilation_metadata
|
186
|
+
)
|
187
|
+
|
188
|
+
def _add_constants_from_classical_code(
|
189
|
+
self, classical_execution_function: CFunc
|
190
|
+
) -> None:
|
191
|
+
# FIXME: https://classiq.atlassian.net/browse/CAD-18050
|
192
|
+
# We use this visitor to add the constants that were used in the classical
|
193
|
+
# execution code to the model. In the future, if we will have a better notion
|
194
|
+
# of "QModule" and a "QConstant" will be a part of it then we may be able to
|
195
|
+
# remove the handling of the QConstants from this visitor, but I think we will
|
196
|
+
# need similar logic to allow using python variables in the classical execution
|
197
|
+
# code
|
198
|
+
class IdentifierVisitor(ast.NodeVisitor):
|
199
|
+
def visit_Name(self, node: ast.Name) -> None:
|
200
|
+
if (
|
201
|
+
node.id in classical_execution_function._caller_constants
|
202
|
+
and isinstance(
|
203
|
+
classical_execution_function._caller_constants[node.id],
|
204
|
+
QConstant,
|
205
|
+
)
|
206
|
+
):
|
207
|
+
classical_execution_function._caller_constants[
|
208
|
+
node.id
|
209
|
+
].add_to_model()
|
210
|
+
|
211
|
+
IdentifierVisitor().visit(ast.parse(classical_execution_function.code))
|
91
212
|
|
92
213
|
|
93
214
|
class ExternalQFunc(QTerminalCallable):
|
215
|
+
_decl: NamedParamsQuantumFunctionDeclaration
|
216
|
+
|
94
217
|
def __init__(self, py_callable: Callable) -> None:
|
95
|
-
|
96
|
-
|
97
|
-
raise ValueError(f"Definition of {py_callable.__name__!r} not found")
|
218
|
+
self._py_callable = py_callable
|
219
|
+
decl = infer_func_decl(py_callable)
|
98
220
|
|
99
221
|
py_callable.__annotations__.pop("return", None)
|
100
222
|
if py_callable.__annotations__.keys() != {
|
101
|
-
mangle_keyword(arg.name) for arg in decl.
|
223
|
+
mangle_keyword(arg.name) for arg in decl.positional_arg_declarations
|
102
224
|
}:
|
103
|
-
raise
|
225
|
+
raise ClassiqError(
|
104
226
|
f"Parameter type hints for {py_callable.__name__!r} do not match imported declaration"
|
105
227
|
)
|
106
228
|
super().__init__(decl)
|
107
229
|
functools.update_wrapper(self, py_callable)
|
108
230
|
|
231
|
+
@property
|
232
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
233
|
+
return self._decl
|
234
|
+
|
235
|
+
@property
|
236
|
+
def pure_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
237
|
+
return self.func_decl
|
238
|
+
|
239
|
+
def get_implementation(self) -> NativeFunctionDefinition:
|
240
|
+
model = QFunc(self._py_callable).create_model()
|
241
|
+
return [
|
242
|
+
func for func in model.functions if func.name == self._py_callable.__name__
|
243
|
+
][0]
|
244
|
+
|
245
|
+
|
246
|
+
class GenerativeQFunc(BaseQFunc):
|
247
|
+
FRAME_DEPTH = 3
|
248
|
+
|
249
|
+
def __init__(
|
250
|
+
self,
|
251
|
+
py_callable: Callable,
|
252
|
+
func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
|
253
|
+
compilation_metadata: Optional[CompilationMetadata] = None,
|
254
|
+
) -> None:
|
255
|
+
super().__init__(py_callable, compilation_metadata)
|
256
|
+
self._func_decl = func_decl
|
257
|
+
|
258
|
+
@property
|
259
|
+
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
260
|
+
if self._func_decl is None:
|
261
|
+
self._func_decl = infer_func_decl(self._py_callable, self._qmodule)
|
262
|
+
return self._func_decl
|
263
|
+
|
264
|
+
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
265
|
+
self._qmodule.generative_functions[self.func_decl.name] = self
|
266
|
+
super().__call__(*args, **kwargs)
|
267
|
+
|
268
|
+
def create_model(
|
269
|
+
self,
|
270
|
+
constraints: Optional[Constraints] = None,
|
271
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
272
|
+
preferences: Optional[Preferences] = None,
|
273
|
+
classical_execution_function: Optional[CFunc] = None,
|
274
|
+
) -> Model:
|
275
|
+
def _dec_main(*args: Any, **kwargs: Any) -> None:
|
276
|
+
self(*args, **kwargs)
|
277
|
+
|
278
|
+
_dec_main.__annotations__ = self._py_callable.__annotations__
|
279
|
+
|
280
|
+
return QFunc(_dec_main).create_model(
|
281
|
+
constraints=constraints,
|
282
|
+
execution_preferences=execution_preferences,
|
283
|
+
preferences=preferences,
|
284
|
+
classical_execution_function=classical_execution_function,
|
285
|
+
)
|
286
|
+
|
109
287
|
|
110
288
|
ILLEGAL_PARAM_ERROR = "Unsupported type hint '{annotation}' for argument '{name}'."
|
111
289
|
|
112
290
|
|
113
291
|
class IllegalParamsError(ClassiqError):
|
114
|
-
_HINT =
|
292
|
+
_HINT = (
|
293
|
+
"\nNote - QMOD functions can declare classical parameters using the type hints "
|
294
|
+
"'CInt', 'CReal', 'CBool', and 'CArray'."
|
295
|
+
)
|
115
296
|
|
116
297
|
def __init__(self, message: str) -> None:
|
117
298
|
super().__init__(message + self._HINT)
|
118
299
|
|
119
300
|
|
120
|
-
def _validate_no_gen_params(annotations:
|
301
|
+
def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
|
121
302
|
_illegal_params = {
|
122
303
|
name: annotation
|
123
304
|
for name, annotation in annotations.items()
|
124
305
|
if not (
|
125
306
|
name == "return"
|
126
|
-
or
|
307
|
+
or (isclass(annotation) and issubclass(annotation, CParam))
|
308
|
+
or (isclass(annotation) and is_dataclass(annotation))
|
309
|
+
or (isclass(annotation) and isinstance(annotation, EnumMeta))
|
310
|
+
or get_origin(annotation) is CArray
|
127
311
|
or (get_origin(annotation) or annotation) is QCallable
|
128
312
|
or (get_origin(annotation) or annotation) is QCallableList
|
129
313
|
or QVar.from_type_hint(annotation) is not None
|
File without changes
|
File without changes
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from collections.abc import Iterator, Mapping
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from classiq.interface.exceptions import ClassiqError
|
6
|
+
from classiq.interface.generator.visitor import Visitor
|
7
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
8
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
9
|
+
from classiq.interface.model.quantum_function_declaration import (
|
10
|
+
AnonQuantumOperandDeclaration,
|
11
|
+
QuantumFunctionDeclaration,
|
12
|
+
QuantumOperandDeclaration,
|
13
|
+
)
|
14
|
+
from classiq.interface.model.quantum_lambda_function import (
|
15
|
+
QuantumLambdaFunction,
|
16
|
+
)
|
17
|
+
|
18
|
+
from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
|
19
|
+
from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
|
20
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
21
|
+
from classiq.qmod.semantics.lambdas import get_renamed_parameters
|
22
|
+
|
23
|
+
|
24
|
+
def _annotate_function_call_decl(
|
25
|
+
fc: QuantumFunctionCall,
|
26
|
+
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
27
|
+
) -> None:
|
28
|
+
if fc._func_decl is None:
|
29
|
+
func_decl = function_dict.get(fc.func_name)
|
30
|
+
if func_decl is None:
|
31
|
+
raise ClassiqError(
|
32
|
+
f"Error resolving function {fc.func_name}, the function is not found in included library."
|
33
|
+
)
|
34
|
+
fc.set_func_decl(func_decl)
|
35
|
+
|
36
|
+
for arg, param in zip(fc.positional_args, fc.func_decl.positional_arg_declarations):
|
37
|
+
if not isinstance(param, AnonQuantumOperandDeclaration):
|
38
|
+
continue
|
39
|
+
args: list
|
40
|
+
if isinstance(arg, list):
|
41
|
+
args = arg
|
42
|
+
else:
|
43
|
+
args = [arg]
|
44
|
+
for qlambda in args:
|
45
|
+
if isinstance(qlambda, QuantumLambdaFunction):
|
46
|
+
qlambda.set_op_decl(param)
|
47
|
+
|
48
|
+
|
49
|
+
class _CallLambdaAnnotator(Visitor):
|
50
|
+
def __init__(
|
51
|
+
self, quantum_functions: Mapping[str, QuantumFunctionDeclaration]
|
52
|
+
) -> None:
|
53
|
+
self._quantum_functions = dict(quantum_functions)
|
54
|
+
self._current_operands: dict[str, QuantumOperandDeclaration] = {}
|
55
|
+
|
56
|
+
@contextmanager
|
57
|
+
def set_operands(
|
58
|
+
self, operands: dict[str, QuantumOperandDeclaration]
|
59
|
+
) -> Iterator[None]:
|
60
|
+
previous_operands = self._current_operands
|
61
|
+
self._current_operands = operands
|
62
|
+
yield
|
63
|
+
self._current_operands = previous_operands
|
64
|
+
|
65
|
+
def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
|
66
|
+
with self.set_operands(func.operand_declarations_dict):
|
67
|
+
self.generic_visit(func)
|
68
|
+
|
69
|
+
def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
|
70
|
+
lambda_operands = get_renamed_parameters(lambda_func)[1]
|
71
|
+
with self.set_operands(self._current_operands | lambda_operands):
|
72
|
+
self.generic_visit(lambda_func)
|
73
|
+
|
74
|
+
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
75
|
+
_annotate_function_call_decl(
|
76
|
+
call, self._quantum_functions | self._current_operands
|
77
|
+
)
|
78
|
+
self.generic_visit(call)
|
79
|
+
|
80
|
+
|
81
|
+
def resolve_function_calls(
|
82
|
+
root: Any,
|
83
|
+
quantum_function_dict: Mapping[str, QuantumFunctionDeclaration],
|
84
|
+
) -> None:
|
85
|
+
all_functions: Mapping[str, QuantumFunctionDeclaration] = {
|
86
|
+
**BUILTIN_FUNCTION_DECLARATIONS,
|
87
|
+
**quantum_function_dict,
|
88
|
+
}
|
89
|
+
with ErrorManager().ignore_errors_context():
|
90
|
+
QStructAnnotator().visit(quantum_function_dict)
|
91
|
+
QStructAnnotator().visit(root)
|
92
|
+
_CallLambdaAnnotator(all_functions).visit(root)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
2
|
+
from classiq.interface.generator.visitor import Visitor
|
3
|
+
|
4
|
+
from classiq.qmod.model_state_container import QMODULE
|
5
|
+
|
6
|
+
|
7
|
+
class QStructAnnotator(Visitor):
|
8
|
+
def __init__(self) -> None:
|
9
|
+
self._visited: set[TypeName] = set()
|
10
|
+
|
11
|
+
def visit_TypeName(self, type_name: TypeName) -> None:
|
12
|
+
decl = QMODULE.qstruct_decls.get(type_name.name)
|
13
|
+
if decl is None or type_name.has_fields or (type_name in self._visited):
|
14
|
+
return
|
15
|
+
self._visited.add(type_name)
|
16
|
+
new_fields = {
|
17
|
+
field_name: field_type.model_copy()
|
18
|
+
for field_name, field_type in decl.fields.items()
|
19
|
+
}
|
20
|
+
# We first visit the new fields and then set to deal with recursive
|
21
|
+
# qstructs
|
22
|
+
self.visit(new_fields)
|
23
|
+
type_name.set_fields(new_fields)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
from collections.abc import Iterator
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from classiq.interface.ast_node import ASTNode
|
6
|
+
from classiq.interface.exceptions import CLASSIQ_SLACK_COMMUNITY_LINK
|
7
|
+
from classiq.interface.source_reference import SourceReferencedError
|
8
|
+
|
9
|
+
|
10
|
+
class ErrorManager:
|
11
|
+
def __new__(cls) -> "ErrorManager":
|
12
|
+
if not hasattr(cls, "_instance"):
|
13
|
+
cls._instance = super().__new__(cls)
|
14
|
+
return cls._instance
|
15
|
+
|
16
|
+
def __init__(self) -> None:
|
17
|
+
if hasattr(self, "_instantiated"):
|
18
|
+
return
|
19
|
+
self._instantiated = True
|
20
|
+
self._errors: list[SourceReferencedError] = []
|
21
|
+
self._current_nodes_stack: list[ASTNode] = []
|
22
|
+
self._call_stack: list[str] = []
|
23
|
+
self._ignore_errors: bool = False
|
24
|
+
|
25
|
+
@contextmanager
|
26
|
+
def ignore_errors_context(self) -> Iterator[None]:
|
27
|
+
previous = self._ignore_errors
|
28
|
+
self._ignore_errors = True
|
29
|
+
try:
|
30
|
+
yield
|
31
|
+
finally:
|
32
|
+
self._ignore_errors = previous
|
33
|
+
|
34
|
+
@property
|
35
|
+
def annotated_errors(self) -> list[str]:
|
36
|
+
return [str(error) for error in self._errors]
|
37
|
+
|
38
|
+
def add_error(self, error: str) -> None:
|
39
|
+
if not self._ignore_errors:
|
40
|
+
self._errors.append(
|
41
|
+
SourceReferencedError(
|
42
|
+
error=error.replace(CLASSIQ_SLACK_COMMUNITY_LINK, ""),
|
43
|
+
source_ref=(
|
44
|
+
self._current_nodes_stack[-1].source_ref
|
45
|
+
if self._current_nodes_stack
|
46
|
+
else None
|
47
|
+
),
|
48
|
+
function=self.current_function,
|
49
|
+
)
|
50
|
+
)
|
51
|
+
|
52
|
+
def get_errors(self) -> list[SourceReferencedError]:
|
53
|
+
return self._errors
|
54
|
+
|
55
|
+
def clear(self) -> None:
|
56
|
+
self._current_nodes_stack = []
|
57
|
+
self._errors = []
|
58
|
+
|
59
|
+
def has_errors(self) -> bool:
|
60
|
+
return len(self._errors) > 0
|
61
|
+
|
62
|
+
def report_errors(self, error_type: type[Exception]) -> None:
|
63
|
+
if self.has_errors():
|
64
|
+
errors = self.annotated_errors
|
65
|
+
self.clear()
|
66
|
+
raise error_type("\n\t" + "\n\t".join(errors))
|
67
|
+
|
68
|
+
@property
|
69
|
+
def current_function(self) -> Optional[str]:
|
70
|
+
return self._call_stack[-1] if self._call_stack else None
|
71
|
+
|
72
|
+
@contextmanager
|
73
|
+
def node_context(self, node: ASTNode) -> Iterator[None]:
|
74
|
+
self._current_nodes_stack.append(node)
|
75
|
+
yield
|
76
|
+
self._current_nodes_stack.pop()
|
77
|
+
|
78
|
+
@contextmanager
|
79
|
+
def call(self, func_name: str) -> Iterator[None]:
|
80
|
+
self._call_stack.append(func_name)
|
81
|
+
yield
|
82
|
+
self._call_stack.pop()
|
83
|
+
|
84
|
+
|
85
|
+
def append_error(node: ASTNode, message: str) -> None:
|
86
|
+
instance = ErrorManager()
|
87
|
+
with instance.node_context(node):
|
88
|
+
instance.add_error(message)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
2
|
+
from classiq.interface.model.quantum_function_declaration import (
|
3
|
+
AnonQuantumOperandDeclaration,
|
4
|
+
QuantumOperandDeclaration,
|
5
|
+
)
|
6
|
+
from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
|
7
|
+
|
8
|
+
from classiq import AnonClassicalParameterDeclaration
|
9
|
+
|
10
|
+
|
11
|
+
def get_renamed_parameters(
|
12
|
+
lambda_func: QuantumLambdaFunction,
|
13
|
+
) -> tuple[list[str], dict[str, QuantumOperandDeclaration], list[PortDeclaration]]:
|
14
|
+
renamed_parameters: list[str] = []
|
15
|
+
renamed_operands: dict[str, QuantumOperandDeclaration] = {}
|
16
|
+
renamed_ports: list[PortDeclaration] = []
|
17
|
+
for idx, param in enumerate(lambda_func.func_decl.positional_arg_declarations):
|
18
|
+
param_name = lambda_func.pos_rename_params[idx]
|
19
|
+
if isinstance(param, AnonClassicalParameterDeclaration):
|
20
|
+
renamed_parameters.append(param_name)
|
21
|
+
elif isinstance(param, AnonQuantumOperandDeclaration):
|
22
|
+
renamed_operands[param_name] = param.rename(param_name)
|
23
|
+
else:
|
24
|
+
renamed_ports.append(param.rename(param_name))
|
25
|
+
return renamed_parameters, renamed_operands, renamed_ports
|