pennylane-lightning-kokkos 0.42.0__cp311-cp311-macosx_13_0_arm64.whl → 0.43.0__cp311-cp311-macosx_13_0_arm64.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.
@@ -41,7 +41,6 @@ try:
41
41
  mpi_error = ex_mpi
42
42
  MPI_SUPPORT = False
43
43
 
44
-
45
44
  except ImportError as ex:
46
45
  warn(str(ex), UserWarning)
47
46
 
@@ -92,7 +92,6 @@ class LightningKokkosStateVector(LightningBaseStateVector):
92
92
  self._mpi = mpi
93
93
 
94
94
  # Initialize the state vector
95
-
96
95
  sv_init_args = [self.num_wires]
97
96
  if mpi:
98
97
  self._mpi_manager = MPIManagerKokkos()
@@ -210,17 +209,21 @@ class LightningKokkosStateVector(LightningBaseStateVector):
210
209
  """Initialize the internal state vector in a specified state.
211
210
  Args:
212
211
  state (Union[array[complex], scipy.SparseABC]): normalized input state of length ``2**len(wires)`` as a dense array or Scipy sparse array.
213
- device_wires (Wires): wires that get initialized in the state
212
+ device_wires (Wires): wires that get initialized in the state.
214
213
  """
215
214
 
216
215
  if sp.sparse.issparse(state):
217
216
  state = state.toarray().flatten()
218
217
 
219
218
  if isinstance(state, self._qubit_state.__class__):
220
- state_data = allocate_aligned_array(state.size, np.dtype(self.dtype), True)
219
+ state_data = allocate_aligned_array(state.size(), np.dtype(self.dtype), True)
221
220
  state.DeviceToHost(state_data)
222
221
  state = state_data
223
222
 
223
+ # Convert PennyLane tensor to NumPy array if needed
224
+ if hasattr(state, "numpy"):
225
+ state = state.numpy()
226
+
224
227
  if len(device_wires) == self._num_wires and Wires(sorted(device_wires)) == device_wires:
225
228
  # Initialize the entire device state with the input state
226
229
  if self._mpi:
@@ -15,8 +15,9 @@ r"""
15
15
  This module contains the :class:`~.LightningKokkos` class, a PennyLane simulator device that
16
16
  interfaces with C++ for fast linear algebra calculations.
17
17
  """
18
+
18
19
  from dataclasses import replace
19
- from functools import reduce
20
+ from functools import partial, reduce
20
21
  from pathlib import Path
21
22
  from typing import List, Optional, Union
22
23
  from warnings import warn
@@ -25,28 +26,30 @@ import numpy as np
25
26
  import pennylane as qml
26
27
  from numpy.random import BitGenerator, Generator, SeedSequence
27
28
  from numpy.typing import ArrayLike
28
- from pennylane.devices import DefaultExecutionConfig, ExecutionConfig
29
+ from pennylane.devices import ExecutionConfig
29
30
  from pennylane.devices.capabilities import OperatorProperties
30
31
  from pennylane.devices.modifiers import simulator_tracking, single_tape_support
31
32
  from pennylane.devices.preprocess import (
32
33
  decompose,
33
- mid_circuit_measurements,
34
+ device_resolve_dynamic_wires,
34
35
  no_sampling,
35
36
  validate_adjoint_trainable_params,
36
37
  validate_device_wires,
37
38
  validate_measurements,
38
39
  validate_observables,
39
40
  )
40
- from pennylane.exceptions import DeviceError
41
+ from pennylane.exceptions import DecompositionUndefinedError, DeviceError
41
42
  from pennylane.measurements import MidMeasureMP
42
- from pennylane.operation import DecompositionUndefinedError, Operator
43
+ from pennylane.operation import Operator
43
44
  from pennylane.ops import Conditional, PauliRot, Prod, SProd, Sum
45
+ from pennylane.transforms import defer_measurements, dynamic_one_shot
44
46
  from pennylane.transforms.core import TransformProgram
45
47
 
46
48
  from pennylane_lightning.lightning_base.lightning_base import (
47
49
  LightningBase,
48
50
  QuantumTape_or_Batch,
49
51
  Result_or_ResultBatch,
52
+ resolve_mcm_method,
50
53
  )
51
54
 
52
55
  try:
@@ -75,28 +78,22 @@ _to_matrix_ops = {
75
78
  }
76
79
 
77
80
 
78
- def stopping_condition(op: Operator) -> bool:
81
+ def stopping_condition(op: Operator, allow_mcms: bool = True) -> bool:
79
82
  """A function that determines whether or not an operation is supported by ``lightning.kokkos``."""
80
83
  if isinstance(op, qml.PauliRot):
81
84
  word = op._hyperparameters["pauli_word"] # pylint: disable=protected-access
82
85
  # decomposes to IsingXX, etc. for n <= 2
83
86
  return reduce(lambda x, y: x + (y != "I"), word, 0) > 2
84
- if op.name in ("C(SProd)", "C(Exp)"):
85
- return True
86
87
 
87
- if (isinstance(op, Conditional) and stopping_condition(op.base)) or isinstance(
88
- op, MidMeasureMP
89
- ):
90
- # Conditional and MidMeasureMP should not be decomposed
91
- return True
88
+ if isinstance(op, MidMeasureMP):
89
+ return allow_mcms
92
90
 
93
91
  return _supports_operation(op.name)
94
92
 
95
93
 
96
- def stopping_condition_shots(op: Operator) -> bool:
97
- """A function that determines whether or not an operation is supported by ``lightning.kokkos``
98
- with finite shots."""
99
- return stopping_condition(op) or isinstance(op, (MidMeasureMP, qml.ops.op_math.Conditional))
94
+ # need to create these once so we can compare in tests
95
+ allow_mcms_stopping_condition = partial(stopping_condition, allow_mcms=True)
96
+ no_mcms_stopping_condition = partial(stopping_condition, allow_mcms=False)
100
97
 
101
98
 
102
99
  def accepted_observables(obs: Operator) -> bool:
@@ -124,12 +121,12 @@ def adjoint_measurements(mp: qml.measurements.MeasurementProcess) -> bool:
124
121
  return isinstance(mp, qml.measurements.ExpectationMP)
125
122
 
126
123
 
127
- def _supports_adjoint(circuit):
124
+ def _supports_adjoint(circuit, device_wires=None):
128
125
  if circuit is None:
129
126
  return True
130
127
 
131
128
  prog = TransformProgram()
132
- _add_adjoint_transforms(prog)
129
+ _add_adjoint_transforms(prog, device_wires=device_wires)
133
130
 
134
131
  try:
135
132
  prog((circuit,))
@@ -147,7 +144,7 @@ def _adjoint_ops(op: qml.operation.Operator) -> bool:
147
144
  )
148
145
 
149
146
 
150
- def _add_adjoint_transforms(program: TransformProgram) -> None:
147
+ def _add_adjoint_transforms(program: TransformProgram, device_wires=None) -> None:
151
148
  """Private helper function for ``preprocess`` that adds the transforms specific
152
149
  for adjoint differentiation.
153
150
 
@@ -165,9 +162,10 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
165
162
  program.add_transform(
166
163
  decompose,
167
164
  stopping_condition=_adjoint_ops,
168
- stopping_condition_shots=stopping_condition_shots,
169
165
  name=name,
170
166
  skip_initial_state_prep=False,
167
+ device_wires=device_wires,
168
+ target_gates=LightningKokkos.capabilities.operations.keys(),
171
169
  )
172
170
  program.add_transform(validate_observables, accepted_observables, name=name)
173
171
  program.add_transform(
@@ -276,10 +274,14 @@ class LightningKokkos(LightningBase):
276
274
  self.LightningMeasurements = LightningKokkosMeasurements
277
275
  self.LightningAdjointJacobian = LightningKokkosAdjointJacobian
278
276
 
279
- def _setup_execution_config(self, config):
277
+ def setup_execution_config(
278
+ self, config: ExecutionConfig | None = None, circuit: qml.tape.QuantumScript | None = None
279
+ ) -> ExecutionConfig:
280
280
  """
281
281
  Update the execution config with choices for how the device should be used and the device options.
282
282
  """
283
+ if config is None:
284
+ config = ExecutionConfig()
283
285
  updated_values = {}
284
286
 
285
287
  # It is necessary to set the mcmc default configuration to complete the requirements of ExecuteConfig
@@ -312,36 +314,13 @@ class LightningKokkos(LightningBase):
312
314
 
313
315
  new_device_options.update(mcmc_default)
314
316
 
315
- mcm_supported_methods = (
316
- ("deferred", "tree-traversal", "one-shot", None)
317
- if not qml.capture.enabled()
318
- else ("deferred", "single-branch-statistics", None)
319
- )
320
-
321
- mcm_config = config.mcm_config
322
-
323
- if (mcm_method := mcm_config.mcm_method) not in mcm_supported_methods:
324
- raise DeviceError(f"mcm_method='{mcm_method}' is not supported with lightning.kokkos.")
325
-
326
- if qml.capture.enabled():
327
-
328
- mcm_updated_values = {}
329
-
330
- if mcm_method == "single-branch-statistics" and mcm_config.postselect_mode is not None:
331
- warn(
332
- "Setting 'postselect_mode' is not supported with mcm_method='single-branch-"
333
- "statistics'. 'postselect_mode' will be ignored.",
334
- UserWarning,
335
- )
336
- mcm_updated_values["postselect_mode"] = None
337
- elif mcm_method is None:
338
- mcm_updated_values["mcm_method"] = "deferred"
339
-
340
- updated_values["mcm_config"] = replace(mcm_config, **mcm_updated_values)
341
-
317
+ mcm_config = resolve_mcm_method(config.mcm_config, circuit, "lightning.kokkos")
318
+ updated_values["mcm_config"] = mcm_config
342
319
  return replace(config, **updated_values, device_options=new_device_options)
343
320
 
344
- def preprocess(self, execution_config: ExecutionConfig = DefaultExecutionConfig):
321
+ def preprocess_transforms(
322
+ self, execution_config: ExecutionConfig | None = None
323
+ ) -> TransformProgram:
345
324
  """This function defines the device transform program to be applied and an updated device configuration.
346
325
 
347
326
  Args:
@@ -360,42 +339,55 @@ class LightningKokkos(LightningBase):
360
339
  * Currently does not intrinsically support parameter broadcasting
361
340
 
362
341
  """
363
- exec_config = self._setup_execution_config(execution_config)
342
+ if execution_config is None:
343
+ execution_config = ExecutionConfig()
344
+ exec_config = execution_config
364
345
  program = TransformProgram()
365
346
 
366
347
  if qml.capture.enabled():
367
-
368
348
  if exec_config.mcm_config.mcm_method == "deferred":
369
349
  program.add_transform(qml.defer_measurements, num_wires=len(self.wires))
370
- # Using stopping_condition_shots because we don't want to decompose Conditionals or MCMs
371
- program.add_transform(qml.transforms.decompose, gate_set=stopping_condition_shots)
372
- return program, exec_config
350
+ program.add_transform(qml.transforms.decompose, gate_set=no_mcms_stopping_condition)
351
+ return program
373
352
 
374
353
  program.add_transform(validate_measurements, name=self.name)
375
354
  program.add_transform(validate_observables, accepted_observables, name=self.name)
376
- program.add_transform(
377
- mid_circuit_measurements, device=self, mcm_config=exec_config.mcm_config
378
- )
379
- program.add_transform(validate_device_wires, self.wires, name=self.name)
355
+ if exec_config.mcm_config.mcm_method == "deferred":
356
+ program.add_transform(defer_measurements, allow_postselect=False)
357
+ _stopping_condition = no_mcms_stopping_condition
358
+ else:
359
+ _stopping_condition = allow_mcms_stopping_condition
380
360
 
381
361
  program.add_transform(
382
362
  decompose,
383
- stopping_condition=stopping_condition,
384
- stopping_condition_shots=stopping_condition_shots,
363
+ stopping_condition=_stopping_condition,
385
364
  skip_initial_state_prep=True,
386
365
  name=self.name,
366
+ device_wires=self.wires,
367
+ target_gates=self.capabilities.operations.keys(),
368
+ )
369
+
370
+ _allow_resets = exec_config.mcm_config.mcm_method != "deferred"
371
+ program.add_transform(
372
+ device_resolve_dynamic_wires, wires=self.wires, allow_resets=_allow_resets
387
373
  )
374
+ program.add_transform(validate_device_wires, self.wires, name=self.name)
375
+ if exec_config.mcm_config.mcm_method == "one-shot":
376
+ program.add_transform(
377
+ dynamic_one_shot, postselect_mode=exec_config.mcm_config.postselect_mode
378
+ )
379
+
388
380
  program.add_transform(qml.transforms.broadcast_expand)
389
381
 
390
382
  if exec_config.gradient_method == "adjoint":
391
- _add_adjoint_transforms(program)
392
- return program, exec_config
383
+ _add_adjoint_transforms(program, device_wires=self.wires)
384
+ return program
393
385
 
394
386
  # pylint: disable=unused-argument
395
387
  def execute(
396
388
  self,
397
389
  circuits: QuantumTape_or_Batch,
398
- execution_config: ExecutionConfig = DefaultExecutionConfig,
390
+ execution_config: ExecutionConfig | None = None,
399
391
  ) -> Result_or_ResultBatch:
400
392
  """Execute a circuit or a batch of circuits and turn it into results.
401
393
 
@@ -406,6 +398,8 @@ class LightningKokkos(LightningBase):
406
398
  Returns:
407
399
  TensorLike, tuple[TensorLike], tuple[tuple[TensorLike]]: A numeric result of the computation.
408
400
  """
401
+ if execution_config is None:
402
+ execution_config = ExecutionConfig()
409
403
  results = []
410
404
  for circuit in circuits:
411
405
  if self._wire_map is not None:
@@ -423,7 +417,7 @@ class LightningKokkos(LightningBase):
423
417
 
424
418
  def supports_derivatives(
425
419
  self,
426
- execution_config: Optional[ExecutionConfig] = None,
420
+ execution_config: ExecutionConfig | None = None,
427
421
  circuit: Optional[qml.tape.QuantumTape] = None,
428
422
  ) -> bool:
429
423
  """Check whether or not derivatives are available for a given configuration and circuit.
@@ -440,11 +434,13 @@ class LightningKokkos(LightningBase):
440
434
  """
441
435
  if execution_config is None and circuit is None:
442
436
  return True
443
- if execution_config.gradient_method not in {"adjoint", "best"}:
444
- return False
445
- if circuit is None:
446
- return True
447
- return _supports_adjoint(circuit=circuit)
437
+
438
+ if execution_config and execution_config.gradient_method in {"adjoint", "best"}:
439
+ if circuit is None:
440
+ return True
441
+ return _supports_adjoint(circuit=circuit, device_wires=self.wires)
442
+
443
+ return False
448
444
 
449
445
  @staticmethod
450
446
  def get_c_interface():
@@ -119,7 +119,7 @@ runtime_code_generation = false
119
119
  # The methods of handling mid-circuit measurements that the device supports, e.g.,
120
120
  # "one-shot", "device", "tree-traversal", etc. An empty list indicates that the device
121
121
  # does not support mid-circuit measurements.
122
- supported_mcm_methods = [ "one-shot", "tree-traversal" ]
122
+ supported_mcm_methods = [ "device", "one-shot", "tree-traversal" ]
123
123
 
124
124
  # Whether the device supports dynamic qubit allocation/deallocation.
125
125
  dynamic_qubit_management = false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pennylane_lightning_kokkos
3
- Version: 0.42.0
3
+ Version: 0.43.0
4
4
  Summary: PennyLane-Lightning plugin
5
5
  Maintainer-email: "Xanadu Quantum Technologies Inc." <software@xanadu.ai>
6
6
  License-Expression: Apache-2.0
@@ -15,17 +15,16 @@ Classifier: Operating System :: POSIX :: Linux
15
15
  Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3 :: Only
18
- Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
22
21
  Classifier: Topic :: Scientific/Engineering :: Physics
23
- Requires-Python: >=3.10
22
+ Requires-Python: >=3.11
24
23
  Description-Content-Type: text/markdown
25
24
  License-File: LICENSE
26
25
  Requires-Dist: pennylane>=0.41
27
26
  Requires-Dist: scipy-openblas32>=0.3.26
28
- Requires-Dist: pennylane_lightning==0.42.0
27
+ Requires-Dist: pennylane_lightning==0.43.0
29
28
  Provides-Extra: gpu
30
29
  Requires-Dist: pennylane-lightning-gpu; extra == "gpu"
31
30
  Provides-Extra: kokkos
@@ -94,7 +93,7 @@ The Lightning plugin ecosystem provides fast state-vector and tensor-network sim
94
93
 
95
94
  [PennyLane](https://docs.pennylane.ai) is a cross-platform Python library for quantum machine
96
95
  learning, automatic differentiation, and optimization of hybrid quantum-classical computations.
97
- PennyLane supports Python 3.10 and above.
96
+ PennyLane supports Python 3.11 and above.
98
97
 
99
98
  ## Backends
100
99
 
@@ -207,7 +206,7 @@ enable the device bindings to PennyLane, which are held to their own respective
207
206
 
208
207
  PennyLane Lightning makes use of the following libraries and tools, which are under their own respective licenses:
209
208
 
210
- - **pybind11:** https://github.com/pybind/pybind11
209
+ - **nanobind:** https://github.com/wjakob/nanobind
211
210
  - **Kokkos Core:** https://github.com/kokkos/kokkos
212
211
  - **NVIDIA cuQuantum:** https://developer.nvidia.com/cuquantum-sdk
213
212
  - **scipy-openblas32:** https://pypi.org/project/scipy-openblas32/
@@ -0,0 +1,14 @@
1
+ pennylane_lightning_kokkos-0.43.0.dist-info/RECORD,,
2
+ pennylane_lightning_kokkos-0.43.0.dist-info/WHEEL,sha256=_2eWE0XUrAnNpxPyXffVnsvXkR9SkDAS3wnEDHyQ9s4,136
3
+ pennylane_lightning_kokkos-0.43.0.dist-info/entry_points.txt,sha256=4ZRRai-y45jgpHOGrbMR_6lbxC5RQ-rm7_96_65kVLM,92
4
+ pennylane_lightning_kokkos-0.43.0.dist-info/top_level.txt,sha256=e3OLLST9VXaQtYnH68djXaL2fbc_-6v6THc_InTmY6o,41
5
+ pennylane_lightning_kokkos-0.43.0.dist-info/METADATA,sha256=GyTL22ttgNmEtxMegE4e_GmT-5QDLvVPYgv2YEoLhho,11204
6
+ pennylane_lightning_kokkos-0.43.0.dist-info/licenses/LICENSE,sha256=_zKpiTfJGLmlVz4pw88ztD4wTe2QkkUNBGSaac54sjM,11720
7
+ pennylane_lightning/lightning_kokkos_ops.cpython-311-darwin.so,sha256=MBl5YjVU88j1AhN5O7ZFE02Vcv3DoVDwgkgGs3PESiI,2163640
8
+ pennylane_lightning/liblightning_kokkos_catalyst.dylib,sha256=vW2HkwTn11IXBDX_AGl4it6Gp_1w5IDIckqcLPlWLyY,1894640
9
+ pennylane_lightning/lightning_kokkos/_state_vector.py,sha256=iVm7Y2w4u4jPCkrXRQzYyP9LKo8C7Wd5ve7HcngyY1A,12787
10
+ pennylane_lightning/lightning_kokkos/_adjoint_jacobian.py,sha256=xLZgfD3WNs2v2khmYHYzA6JJjlXRxvOC24x2EFd1xVg,4700
11
+ pennylane_lightning/lightning_kokkos/_measurements.py,sha256=6LqVSSMdZQKb8UtagmWV8MzTzxzDApLJ-hc50V9kZko,3352
12
+ pennylane_lightning/lightning_kokkos/lightning_kokkos.py,sha256=FEcrfgdavtZmVWs_2Q6nwn9KXGjFjObxeczCnZwPtK8,18163
13
+ pennylane_lightning/lightning_kokkos/__init__.py,sha256=b5bC5e_6CY9RPZQBeUhLE6l6ecAc8ocGCb2S4K_Ym7I,737
14
+ pennylane_lightning/lightning_kokkos/lightning_kokkos.toml,sha256=kYJBmnO5oc0lRnjwfxPNaR5Dpp-ZbyKi3YM8I7JbpG8,7282
@@ -2,4 +2,5 @@ Wheel-Version: 1.0
2
2
  Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp311-cp311-macosx_13_0_arm64
5
+ Generator: delocate 0.13.0
5
6
 
@@ -1,14 +0,0 @@
1
- pennylane_lightning_kokkos-0.42.0.dist-info/RECORD,,
2
- pennylane_lightning_kokkos-0.42.0.dist-info/WHEEL,sha256=yC0XNaoYiBgQXLLHbXmHbYPH-k8OLhqcw3z1Ch6GPfE,109
3
- pennylane_lightning_kokkos-0.42.0.dist-info/entry_points.txt,sha256=4ZRRai-y45jgpHOGrbMR_6lbxC5RQ-rm7_96_65kVLM,92
4
- pennylane_lightning_kokkos-0.42.0.dist-info/top_level.txt,sha256=e3OLLST9VXaQtYnH68djXaL2fbc_-6v6THc_InTmY6o,41
5
- pennylane_lightning_kokkos-0.42.0.dist-info/METADATA,sha256=eLxvCSuzDMlBMcON4B9-3xOhcSr70WjlxhQsauzPfBY,11255
6
- pennylane_lightning_kokkos-0.42.0.dist-info/licenses/LICENSE,sha256=_zKpiTfJGLmlVz4pw88ztD4wTe2QkkUNBGSaac54sjM,11720
7
- pennylane_lightning/lightning_kokkos_ops.cpython-311-darwin.so,sha256=gvZAj-Cky1T4eQlLQrZlxU8O2CE8PxPKz04duIdG5hA,2279304
8
- pennylane_lightning/liblightning_kokkos_catalyst.dylib,sha256=gHOs-JK-5KHiQsANkmkRCGyFSAGsdOr7hx7zw-bb0aI,1868704
9
- pennylane_lightning/lightning_kokkos/_state_vector.py,sha256=UNpfehgvrFta2-sDBMbGwlVSfBI9bjw1GLGNSSV_LGA,12654
10
- pennylane_lightning/lightning_kokkos/_adjoint_jacobian.py,sha256=yUc6dm9xosiltVlCnBovJFvJdPbamhu_sgkex9LPZ5I,4701
11
- pennylane_lightning/lightning_kokkos/_measurements.py,sha256=6LqVSSMdZQKb8UtagmWV8MzTzxzDApLJ-hc50V9kZko,3352
12
- pennylane_lightning/lightning_kokkos/lightning_kokkos.py,sha256=Xoe3WvcNCFMGfG47SZ4rTpFyQ27rkZQAenO0u9SWuoE,18286
13
- pennylane_lightning/lightning_kokkos/__init__.py,sha256=b5bC5e_6CY9RPZQBeUhLE6l6ecAc8ocGCb2S4K_Ym7I,737
14
- pennylane_lightning/lightning_kokkos/lightning_kokkos.toml,sha256=TiQr1-43aSioFsh1lSnG_t09tktPaEwUSnUd3sNEtGA,7272