classiq 0.38.0__py3-none-any.whl → 0.65.4__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.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/WHEEL +0 -0
classiq/execution/jobs.py CHANGED
@@ -1,24 +1,39 @@
1
1
  import webbrowser
2
2
  from datetime import datetime
3
- from typing import List, Optional, Union
3
+ from typing import Any, Optional, Union
4
4
  from urllib.parse import urljoin
5
5
 
6
+ import httpx
7
+
8
+ from classiq.interface.exceptions import (
9
+ ClassiqAPIError,
10
+ ClassiqError,
11
+ )
6
12
  from classiq.interface.execution.jobs import ExecutionJobDetailsV1
7
- from classiq.interface.executor.execution_request import ExecutionJobDetails
13
+ from classiq.interface.executor.execution_request import ExecutionJobDetails, JobCost
8
14
  from classiq.interface.executor.execution_result import ResultsCollection
15
+ from classiq.interface.executor.result import (
16
+ EstimationResult,
17
+ EstimationResults,
18
+ ExecutionDetails,
19
+ MultipleExecutionDetails,
20
+ )
9
21
  from classiq.interface.jobs import JobStatus, JSONObject
10
- from classiq.interface.server.routes import EXECUTION_JOBS_NON_VERSIONED_FULL_PATH
22
+ from classiq.interface.server.routes import EXECUTION_JOBS_FULL_PATH
11
23
 
12
- from classiq._internals.api_wrapper import CLASSIQ_ACCEPT_HEADER, ApiWrapper
24
+ from classiq._internals.api_wrapper import ApiWrapper
13
25
  from classiq._internals.async_utils import syncify_function
14
26
  from classiq._internals.client import client
15
27
  from classiq._internals.jobs import JobID, JobPoller
16
- from classiq.exceptions import ClassiqAPIError
17
28
 
18
29
  _JobDetails = Union[ExecutionJobDetails, ExecutionJobDetailsV1]
19
30
 
20
- _JOB_DETAILS_VERSION = "v1"
21
- _JOB_RESULT_VERSION = "v1"
31
+
32
+ class ClassiqExecutionResultError(ClassiqError):
33
+ def __init__(self, primitive: str) -> None:
34
+ super().__init__(
35
+ f"Execution job does not contain a single {primitive!r} result, make sure you use the 'get_*_result' method matching the primitive you executed. You can use the 'result' method to see the general result."
36
+ )
22
37
 
23
38
 
24
39
  class ExecutionJob:
@@ -76,23 +91,44 @@ class ExecutionJob:
76
91
  else:
77
92
  return f"{class_name}(name={self.name!r}, id={self.id!r})"
78
93
 
94
+ def cost(self, *, verbose: bool = False) -> Union[str, JobCost]:
95
+ if self._details.cost is None:
96
+ self._details.cost = JobCost()
97
+ if verbose:
98
+ return self._details.cost
99
+ return f"{self._details.cost.total_cost} {self._details.cost.currency_code}"
100
+
79
101
  @classmethod
80
- async def from_id_async(cls, id: str) -> "ExecutionJob":
81
- details = await ApiWrapper.call_get_execution_job_details(JobID(job_id=id))
102
+ async def from_id_async(
103
+ cls,
104
+ id: str,
105
+ _http_client: Optional[httpx.AsyncClient] = None,
106
+ ) -> "ExecutionJob":
107
+ details = await ApiWrapper.call_get_execution_job_details(
108
+ JobID(job_id=id), http_client=_http_client
109
+ )
82
110
  return cls(details)
83
111
 
112
+ # `syncify_function` doesn't work well for class methods, so I wrote `from_id`
113
+ # explicitly
84
114
  @classmethod
85
- def from_id(cls, id: str) -> "ExecutionJob":
86
- return syncify_function(cls.from_id_async)(id)
115
+ def from_id(
116
+ cls,
117
+ id: str,
118
+ _http_client: Optional[httpx.AsyncClient] = None,
119
+ ) -> "ExecutionJob":
120
+ return syncify_function(cls.from_id_async)(id, _http_client=_http_client)
87
121
 
88
122
  @property
89
123
  def _job_id(self) -> JobID:
90
124
  return JobID(job_id=self.id)
91
125
 
92
126
  async def result_async(
93
- self, timeout_sec: Optional[float] = None
127
+ self,
128
+ timeout_sec: Optional[float] = None,
129
+ _http_client: Optional[httpx.AsyncClient] = None,
94
130
  ) -> ResultsCollection:
95
- await self.poll_async(timeout_sec=timeout_sec)
131
+ await self.poll_async(timeout_sec=timeout_sec, _http_client=_http_client)
96
132
 
97
133
  if self.status == JobStatus.FAILED:
98
134
  raise ClassiqAPIError(self.error or "")
@@ -102,45 +138,181 @@ class ExecutionJob:
102
138
  if self._result is None:
103
139
  self._result = (
104
140
  await ApiWrapper.call_get_execution_job_result(
105
- job_id=self._job_id, version=_JOB_RESULT_VERSION
141
+ job_id=self._job_id,
142
+ http_client=_http_client,
106
143
  )
107
144
  ).results
108
145
  return self._result
109
146
 
110
147
  result = syncify_function(result_async)
111
148
 
112
- async def poll_async(self, timeout_sec: Optional[float] = None) -> None:
149
+ def result_value(self, *args: Any, **kwargs: Any) -> Any:
150
+ return self.result(*args, **kwargs)[0].value
151
+
152
+ def get_sample_result(
153
+ self, _http_client: Optional[httpx.AsyncClient] = None
154
+ ) -> ExecutionDetails:
155
+ """
156
+ Returns the job's result as a single sample result after validation. If the result is not yet available, waits for it.
157
+
158
+ Returns:
159
+ The sample result of the execution job.
160
+
161
+ Raises:
162
+ ClassiqExecutionResultError: In case the result does not contain a single sample result.
163
+ ClassiqAPIError: In case the job has failed.
164
+ """
165
+ results = self.result(_http_client=_http_client)
166
+ if len(results) != 1:
167
+ raise ClassiqExecutionResultError("sample")
168
+
169
+ result = results[0].value
170
+ if isinstance(result, ExecutionDetails):
171
+ return result
172
+ if isinstance(result, MultipleExecutionDetails) and len(result.details) == 1:
173
+ return result.details[0]
174
+ raise ClassiqExecutionResultError("sample")
175
+
176
+ def get_batch_sample_result(
177
+ self, _http_client: Optional[httpx.AsyncClient] = None
178
+ ) -> list[ExecutionDetails]:
179
+ """
180
+ Returns the job's result as a single batch_sample result after validation. If the result is not yet available, waits for it.
181
+
182
+ Returns:
183
+ The batch_sample result of the execution job.
184
+
185
+ Raises:
186
+ ClassiqExecutionResultError: In case the result does not contain a single batch_sample result.
187
+ ClassiqAPIError: In case the job has failed.
188
+ """
189
+ results = self.result(_http_client=_http_client)
190
+ if len(results) != 1:
191
+ raise ClassiqExecutionResultError("batch_sample")
192
+
193
+ result = results[0].value
194
+ if isinstance(result, ExecutionDetails):
195
+ return [result]
196
+ if isinstance(result, MultipleExecutionDetails):
197
+ return result.details
198
+
199
+ raise ClassiqExecutionResultError("batch_sample")
200
+
201
+ def get_estimate_result(
202
+ self, _http_client: Optional[httpx.AsyncClient] = None
203
+ ) -> EstimationResult:
204
+ """
205
+ Returns the job's result as a single estimate result after validation. If the result is not yet available, waits for it.
206
+
207
+ Returns:
208
+ The estimate result of the execution job.
209
+
210
+ Raises:
211
+ ClassiqExecutionResultError: In case the result does not contain a single estimate result.
212
+ ClassiqAPIError: In case the job has failed.
213
+ """
214
+ results = self.result(_http_client=_http_client)
215
+ if len(results) != 1:
216
+ raise ClassiqExecutionResultError("estimate")
217
+
218
+ result = results[0].value
219
+ if isinstance(result, EstimationResult):
220
+ return result
221
+ if isinstance(result, EstimationResults) and len(result.results) == 1:
222
+ return result.results[0]
223
+ raise ClassiqExecutionResultError("estimate")
224
+
225
+ def get_batch_estimate_result(
226
+ self, _http_client: Optional[httpx.AsyncClient] = None
227
+ ) -> list[EstimationResult]:
228
+ """
229
+ Returns the job's result as a single batch_estimate result after validation. If the result is not yet available, waits for it.
230
+
231
+ Returns:
232
+ The batch_estimate result of the execution job.
233
+
234
+ Raises:
235
+ ClassiqExecutionResultError: In case the result does not contain a single batch_estimate result.
236
+ ClassiqAPIError: In case the job has failed.
237
+ """
238
+ results = self.result(_http_client=_http_client)
239
+ if len(results) != 1:
240
+ raise ClassiqExecutionResultError("batch_estimate")
241
+
242
+ result = results[0].value
243
+ if isinstance(result, EstimationResult):
244
+ return [result]
245
+ if isinstance(result, EstimationResults):
246
+ return result.results
247
+
248
+ raise ClassiqExecutionResultError("batch_estimate")
249
+
250
+ async def poll_async(
251
+ self,
252
+ timeout_sec: Optional[float] = None,
253
+ _http_client: Optional[httpx.AsyncClient] = None,
254
+ ) -> None:
113
255
  if not self.status.is_final():
114
- await self._poll_job(timeout_sec=timeout_sec)
256
+ await self._poll_job(timeout_sec=timeout_sec, _http_client=_http_client)
115
257
 
116
258
  poll = syncify_function(poll_async)
117
259
 
118
- async def _poll_job(self, timeout_sec: Optional[float] = None) -> None:
260
+ async def _poll_job(
261
+ self,
262
+ timeout_sec: Optional[float] = None,
263
+ _http_client: Optional[httpx.AsyncClient] = None,
264
+ ) -> None:
119
265
  def response_parser(json_response: JSONObject) -> Optional[bool]:
120
- self._details = ExecutionJobDetails.parse_obj(json_response)
266
+ self._details = ExecutionJobDetails.model_validate(json_response)
121
267
  if self.status.is_final():
122
268
  return True
123
269
  return None
124
270
 
125
271
  poller = JobPoller(
126
- base_url=EXECUTION_JOBS_NON_VERSIONED_FULL_PATH,
127
- use_versioned_url=False,
128
- additional_headers={CLASSIQ_ACCEPT_HEADER: _JOB_DETAILS_VERSION},
272
+ base_url=EXECUTION_JOBS_FULL_PATH,
129
273
  )
130
274
  await poller.poll(
131
275
  job_id=self._job_id,
132
276
  response_parser=response_parser,
133
277
  timeout_sec=timeout_sec,
278
+ http_client=_http_client,
134
279
  )
135
280
 
136
- async def rename_async(self, name: str) -> None:
137
- self._details = await ApiWrapper.call_patch_execution_job(self._job_id, name)
281
+ async def rename_async(
282
+ self,
283
+ name: str,
284
+ _http_client: Optional[httpx.AsyncClient] = None,
285
+ ) -> None:
286
+ self._details = await ApiWrapper.call_patch_execution_job(
287
+ self._job_id,
288
+ name,
289
+ http_client=_http_client,
290
+ )
138
291
 
139
292
  rename = syncify_function(rename_async)
140
293
 
294
+ async def cancel_async(
295
+ self,
296
+ _http_client: Optional[httpx.AsyncClient] = None,
297
+ ) -> None:
298
+ """
299
+ Cancels the execution job. This implies the cancellation of any ongoing jobs
300
+ sent to the provider during this execution job.
301
+
302
+ The function returns without waiting to the actual cancellation. It is possible
303
+ to continue polling the job in order to ensure its cancellation, which might
304
+ not be immediate.
305
+ """
306
+ await ApiWrapper.call_cancel_execution_job(
307
+ self._job_id,
308
+ http_client=_http_client,
309
+ )
310
+
311
+ cancel = syncify_function(cancel_async)
312
+
141
313
  @property
142
314
  def ide_url(self) -> str:
143
- base_url = client().config.ide
315
+ base_url = client().config.ide.unicode_string()
144
316
  return urljoin(base_url, f"jobs/{self.id}")
145
317
 
146
318
  def open_in_ide(self) -> None:
@@ -149,7 +321,7 @@ class ExecutionJob:
149
321
 
150
322
  async def get_execution_jobs_async(
151
323
  offset: int = 0, limit: int = 50
152
- ) -> List[ExecutionJob]:
324
+ ) -> list[ExecutionJob]:
153
325
  result = await ApiWrapper().call_query_execution_jobs(offset=offset, limit=limit)
154
326
  return [ExecutionJob(details) for details in result.results]
155
327
 
@@ -0,0 +1,79 @@
1
+ import functools
2
+ from typing import Optional
3
+
4
+ import more_itertools
5
+
6
+ from classiq.interface.chemistry.operator import PauliOperator
7
+ from classiq.interface.executor.constants import DEFAULT_RESULT_NAME
8
+ from classiq.interface.executor.execution_result import (
9
+ ResultsCollection,
10
+ SavedResultValueType,
11
+ TaggedEstimationResult,
12
+ TaggedExecutionDetails,
13
+ )
14
+ from classiq.interface.executor.quantum_code import Arguments, MultipleArguments
15
+
16
+ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
17
+ pauli_operator_to_hamiltonian,
18
+ )
19
+ from classiq.execution.execution_session import ExecutionSession
20
+ from classiq.synthesis import SerializedQuantumProgram
21
+
22
+ _MAX_ARGUMENTS_SIZE = 1024
23
+
24
+
25
+ def _execute_qnn_estimate(
26
+ session: ExecutionSession,
27
+ arguments: list[Arguments],
28
+ observable: PauliOperator,
29
+ ) -> ResultsCollection:
30
+ hamiltonian = pauli_operator_to_hamiltonian(observable.pauli_list)
31
+ return [
32
+ TaggedEstimationResult(
33
+ name=DEFAULT_RESULT_NAME,
34
+ value=result,
35
+ value_type=SavedResultValueType.EstimationResult,
36
+ )
37
+ for result in session.batch_estimate(
38
+ hamiltonian=hamiltonian, parameters=arguments
39
+ )
40
+ ]
41
+
42
+
43
+ def _execute_qnn_sample(
44
+ session: ExecutionSession,
45
+ arguments: list[Arguments],
46
+ ) -> ResultsCollection:
47
+ return [
48
+ TaggedExecutionDetails(
49
+ name=DEFAULT_RESULT_NAME,
50
+ value=result,
51
+ value_type=SavedResultValueType.ExecutionDetails,
52
+ )
53
+ for result in session.batch_sample(arguments)
54
+ ]
55
+
56
+
57
+ def execute_qnn(
58
+ quantum_program: SerializedQuantumProgram,
59
+ arguments: MultipleArguments,
60
+ observable: Optional[PauliOperator] = None,
61
+ ) -> ResultsCollection:
62
+ with ExecutionSession(quantum_program) as session:
63
+ if observable:
64
+ execute_function = functools.partial(
65
+ _execute_qnn_estimate,
66
+ session=session,
67
+ observable=observable,
68
+ )
69
+ else:
70
+ execute_function = functools.partial(
71
+ _execute_qnn_sample,
72
+ session=session,
73
+ )
74
+
75
+ result: ResultsCollection = []
76
+ for chunk in more_itertools.chunked(arguments, _MAX_ARGUMENTS_SIZE):
77
+ chunk_result = execute_function(arguments=chunk)
78
+ result.extend(chunk_result)
79
+ return result
classiq/executor.py CHANGED
@@ -1,135 +1,55 @@
1
1
  """Executor module, implementing facilities for executing quantum programs using Classiq platform."""
2
2
 
3
- import functools
4
- from typing import Optional, Tuple, Union
3
+ from typing import Union
5
4
 
6
- import more_itertools
7
5
  from typing_extensions import TypeAlias
8
6
 
9
7
  from classiq.interface.backend.backend_preferences import BackendPreferencesTypes
10
- from classiq.interface.chemistry.operator import PauliOperators
11
8
  from classiq.interface.executor.estimation import OperatorsEstimation
12
9
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
13
- from classiq.interface.executor.execution_request import (
14
- EstimateOperatorsExecution,
15
- ExecutionRequest,
16
- QuantumCodeExecution,
17
- )
18
- from classiq.interface.executor.execution_result import (
19
- ResultsCollection,
20
- SavedResultValueType,
21
- TaggedEstimationResult,
22
- TaggedExecutionDetails,
23
- )
24
- from classiq.interface.executor.quantum_code import MultipleArguments, QuantumCode
10
+ from classiq.interface.executor.quantum_code import QuantumCode
25
11
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
26
12
  from classiq.interface.executor.result import ExecutionDetails
27
13
  from classiq.interface.generator.quantum_program import QuantumProgram
28
14
 
15
+ from classiq._internals import async_utils
29
16
  from classiq._internals.api_wrapper import ApiWrapper
30
- from classiq._internals.async_utils import syncify_function
31
17
  from classiq.execution.jobs import ExecutionJob
32
- from classiq.model.model import DEFAULT_RESULT_NAME
33
18
  from classiq.synthesis import SerializedQuantumProgram
34
19
 
35
20
  BatchExecutionResult: TypeAlias = Union[ExecutionDetails, BaseException]
36
- ProgramAndResult: TypeAlias = Tuple[QuantumCode, BatchExecutionResult]
37
- BackendPreferencesAndResult: TypeAlias = Tuple[
21
+ ProgramAndResult: TypeAlias = tuple[QuantumCode, BatchExecutionResult]
22
+ BackendPreferencesAndResult: TypeAlias = tuple[
38
23
  BackendPreferencesTypes, int, BatchExecutionResult
39
24
  ]
40
- _MAX_ARGUMENTS_SIZE = 1024
41
25
 
42
26
 
43
27
  def _parse_serialized_qprog(
44
28
  quantum_program: SerializedQuantumProgram,
45
29
  ) -> QuantumProgram:
46
- return QuantumProgram.parse_raw(quantum_program)
30
+ return QuantumProgram.model_validate_json(quantum_program)
47
31
 
48
32
 
49
33
  async def execute_async(quantum_program: SerializedQuantumProgram) -> ExecutionJob:
50
34
  circuit = _parse_serialized_qprog(quantum_program)
51
- result = await ApiWrapper.call_execute_generated_circuit(circuit)
35
+ execution_input = await ApiWrapper.call_convert_quantum_program(circuit)
36
+ result = await ApiWrapper.call_execute_execution_input(execution_input)
52
37
  return ExecutionJob(details=result)
53
38
 
54
39
 
55
- execute = syncify_function(execute_async)
56
-
57
-
58
- async def _execute_qnn_async_estimate(
59
- quantum_program: QuantumCode,
60
- execution_preferences: ExecutionPreferences,
61
- observables: PauliOperators,
62
- ) -> ResultsCollection:
63
- request = ExecutionRequest(
64
- execution_payload=EstimateOperatorsExecution(
65
- quantum_program=quantum_program,
66
- operators=observables,
67
- ),
68
- preferences=execution_preferences,
69
- )
70
-
71
- results = await ApiWrapper.call_execute_estimate(request)
72
- return [
73
- TaggedEstimationResult(
74
- name=DEFAULT_RESULT_NAME,
75
- value=result,
76
- value_type=SavedResultValueType.EstimationResult,
77
- )
78
- for result in results
79
- ]
80
-
81
-
82
- async def _execute_qnn_async_program(
83
- quantum_program: QuantumCode,
84
- execution_preferences: ExecutionPreferences,
85
- ) -> ResultsCollection:
86
- request = ExecutionRequest(
87
- execution_payload=QuantumCodeExecution(**quantum_program.dict()),
88
- preferences=execution_preferences,
89
- )
90
-
91
- api_result = await ApiWrapper.call_execute_quantum_program(request)
92
- return [
93
- TaggedExecutionDetails(
94
- name=DEFAULT_RESULT_NAME,
95
- value=result,
96
- value_type=SavedResultValueType.ExecutionDetails,
97
- )
98
- for result in api_result.details
99
- ]
100
-
101
-
102
- async def execute_qnn_async(
103
- quantum_program: SerializedQuantumProgram,
104
- arguments: MultipleArguments,
105
- observables: Optional[PauliOperators] = None,
106
- ) -> ResultsCollection:
107
- circuit = _parse_serialized_qprog(quantum_program)
108
- execution_preferences = circuit.model.execution_preferences
109
-
110
- legacy_quantum_program = circuit.to_program()
111
-
112
- if observables:
113
- execute_function = functools.partial(
114
- _execute_qnn_async_estimate,
115
- execution_preferences=execution_preferences,
116
- observables=observables,
117
- )
118
- else:
119
- execute_function = functools.partial(
120
- _execute_qnn_async_program,
121
- execution_preferences=execution_preferences,
122
- )
40
+ def execute(quantum_program: SerializedQuantumProgram) -> ExecutionJob:
41
+ """
42
+ Execute a quantum program. The preferences for execution are set on the quantum program using the method `set_execution_preferences`.
123
43
 
124
- result: ResultsCollection = []
125
- for chunk in more_itertools.chunked(arguments, _MAX_ARGUMENTS_SIZE):
126
- legacy_quantum_program.arguments = tuple(chunk)
127
- chunk_result = await execute_function(quantum_program=legacy_quantum_program)
128
- result.extend(chunk_result)
129
- return result
44
+ Args:
45
+ quantum_program: The quantum program to execute. This is the result of the synthesize method.
130
46
 
47
+ Returns:
48
+ ExecutionJob: The result of the execution.
131
49
 
132
- execute_qnn = syncify_function(execute_qnn_async)
50
+ For examples please see [Execution Documentation](https://docs.classiq.io/latest/user-guide/execution/)
51
+ """
52
+ return async_utils.run(execute_async(quantum_program))
133
53
 
134
54
 
135
55
  def set_quantum_program_execution_preferences(
@@ -138,27 +58,12 @@ def set_quantum_program_execution_preferences(
138
58
  ) -> SerializedQuantumProgram:
139
59
  circuit = _parse_serialized_qprog(quantum_program)
140
60
  circuit.model.execution_preferences = preferences
141
- return SerializedQuantumProgram(circuit.json())
142
-
143
-
144
- def set_initial_values(
145
- quantum_program: SerializedQuantumProgram,
146
- **kwargs: int,
147
- ) -> SerializedQuantumProgram:
148
- circuit = _parse_serialized_qprog(quantum_program)
149
- circuit.initial_values = kwargs
150
-
151
- # Validate the initial values by calling `get_registers_initialization`
152
- circuit.get_registers_initialization(circuit.initial_values)
153
-
154
- return SerializedQuantumProgram(circuit.json())
61
+ return SerializedQuantumProgram(circuit.model_dump_json())
155
62
 
156
63
 
157
64
  __all__ = [
65
+ "OperatorsEstimation",
158
66
  "QuantumCode",
159
67
  "QuantumInstructionSet",
160
- "execute_qnn",
161
- "OperatorsEstimation",
162
68
  "set_quantum_program_execution_preferences",
163
- "set_initial_values",
164
69
  ]
@@ -3,5 +3,5 @@ from packaging.version import Version
3
3
  # This file was generated automatically
4
4
  # Please don't track in version control (DONTTRACK)
5
5
 
6
- SEMVER_VERSION = '0.38.0'
6
+ SEMVER_VERSION = '0.65.4'
7
7
  VERSION = str(Version(SEMVER_VERSION))
@@ -1,8 +1,8 @@
1
- from typing import Dict, List, Optional
1
+ from typing import Annotated, Optional
2
2
 
3
3
  import numpy
4
4
  import pydantic
5
- from pydantic import Field
5
+ from pydantic import ConfigDict, Field, StringConstraints
6
6
 
7
7
  from classiq.interface.backend.quantum_backend_providers import AnalyzerProviderVendor
8
8
  from classiq.interface.chemistry.ground_state_problem import MoleculeProblem
@@ -17,22 +17,29 @@ from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyStri
17
17
  MAX_KB_OF_FILE = 500
18
18
  MAX_FILE_LENGTH = MAX_KB_OF_FILE * 1024
19
19
 
20
+ MAX_QUBITS = 100
21
+ MIN_QUBITS = 0
22
+ MAX_COUNTS = 1000
23
+ MAX_NUM_CLIFFORD = 1000
24
+ MAX_NAME_LENGTH = 100
25
+
20
26
 
21
27
  class AnalysisParams(pydantic.BaseModel):
22
28
  qasm: PydanticNonEmptyString = Field(..., max_length=MAX_FILE_LENGTH)
23
29
 
24
30
 
25
31
  class HardwareListParams(pydantic.BaseModel):
26
- devices: Optional[List[PydanticNonEmptyString]] = pydantic.Field(
32
+ devices: Optional[list[PydanticNonEmptyString]] = pydantic.Field(
27
33
  default=None, description="Devices"
28
34
  )
29
- providers: List[Provider]
35
+ providers: list[Provider]
30
36
  from_ide: bool = Field(default=False)
31
37
 
32
- @pydantic.validator("providers", always=True)
38
+ @pydantic.field_validator("providers")
39
+ @classmethod
33
40
  def set_default_providers(
34
- cls, providers: Optional[List[AnalyzerProviderVendor]]
35
- ) -> List[AnalyzerProviderVendor]:
41
+ cls, providers: Optional[list[AnalyzerProviderVendor]]
42
+ ) -> list[AnalyzerProviderVendor]:
36
43
  if providers is None:
37
44
  providers = list(AnalyzerProviderVendor)
38
45
  return providers
@@ -40,12 +47,30 @@ class HardwareListParams(pydantic.BaseModel):
40
47
 
41
48
  class AnalysisOptionalDevicesParams(HardwareListParams):
42
49
  qubit_count: int = pydantic.Field(
43
- default=..., description="number of qubits in the data"
50
+ default=...,
51
+ description="number of qubits in the data",
52
+ ge=MIN_QUBITS,
53
+ le=MAX_QUBITS,
54
+ )
55
+
56
+
57
+ class GateNamsMapping(pydantic.BaseModel):
58
+ qasm_name: Annotated[
59
+ str, Annotated[str, StringConstraints(max_length=MAX_NAME_LENGTH)]
60
+ ]
61
+ display_name: Annotated[
62
+ str, Annotated[str, StringConstraints(max_length=MAX_NAME_LENGTH)]
63
+ ]
64
+
65
+
66
+ class LatexParams(AnalysisParams):
67
+ gate_names: list[GateNamsMapping] = pydantic.Field(
68
+ default=..., description="List of gate names as apper in the qasm"
44
69
  )
45
70
 
46
71
 
47
72
  class AnalysisHardwareTranspilationParams(pydantic.BaseModel):
48
- hardware_data: Optional[SynthesisHardwareData]
73
+ hardware_data: Optional[SynthesisHardwareData] = None
49
74
  random_seed: int
50
75
  transpilation_option: TranspilationOption
51
76
 
@@ -70,13 +95,18 @@ class CircuitAnalysisHardwareParams(AnalysisParams):
70
95
 
71
96
  class AnalysisRBParams(pydantic.BaseModel):
72
97
  hardware: str
73
- counts: List[Dict[str, int]]
74
- num_clifford: List[int]
98
+ counts: list[
99
+ dict[
100
+ str, Annotated[int, Annotated[int, Field(strict=True, gt=0, le=MAX_COUNTS)]]
101
+ ]
102
+ ]
103
+ num_clifford: list[
104
+ Annotated[int, Annotated[int, Field(strict=True, gt=0, le=MAX_NUM_CLIFFORD)]]
105
+ ]
75
106
 
76
107
 
77
108
  class ChemistryGenerationParams(pydantic.BaseModel):
78
- class Config:
79
- title = "Chemistry"
109
+ model_config = ConfigDict(title="Chemistry")
80
110
 
81
111
  molecule: MoleculeProblem = pydantic.Field(
82
112
  title="Molecule",