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