Skip to content

Commit

Permalink
cleaning code
Browse files Browse the repository at this point in the history
  • Loading branch information
LuisAlfredoNu committed Sep 11, 2024
1 parent c7ac82d commit 6627913
Show file tree
Hide file tree
Showing 11 changed files with 37 additions and 116 deletions.
21 changes: 0 additions & 21 deletions pennylane_lightning/core/_measurements_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,27 +140,6 @@ def probs(self, measurementprocess: MeasurementProcess):
Returns:
Probabilities of the supplied observable or wires
"""
# diagonalizing_gates = measurementprocess.diagonalizing_gates()
# # print('*'*100)
# # print("probs: diagonalizing_gates:", diagonalizing_gates)
# if diagonalizing_gates:
# self._qubit_state.apply_operations(diagonalizing_gates)
# results = self._measurement_lightning.probs(measurementprocess.wires.tolist())

# # print("probs: result:",results)
# # print('*'*100)
# if diagonalizing_gates:
# self._qubit_state.apply_operations(
# [qml.adjoint(g, lazy=False) for g in reversed(diagonalizing_gates)]
# )

# # Device returns as col-major orderings, so perform transpose on data for bit-index shuffle for now.
# if len(results) > 0:
# num_local_wires = len(results).bit_length() - 1 if len(results) > 0 else 0
# return results.reshape([2] * num_local_wires).transpose().reshape(-1)

# return results


def var(self, measurementprocess: MeasurementProcess):
"""Variance of the supplied observable contained in the MeasurementProcess.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ class Measurements final
PL_CUSTATEVEC_IS_SUCCESS(custatevecSamplerSample(
this->_statevector.getCusvHandle(), sampler, bitStrings.data(),
bitOrdering.data(), bitStringLen, rand_nums.data(), num_samples,
// CUSTATEVEC_SAMPLER_OUTPUT_ASCENDING_ORDER));
CUSTATEVEC_SAMPLER_OUTPUT_RANDNUM_ORDER));
PL_CUDA_IS_SUCCESS(cudaStreamSynchronize(
this->_statevector.getDataBuffer().getDevTag().getStreamID()));
Expand Down
1 change: 1 addition & 0 deletions pennylane_lightning/lightning_gpu/_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def probs(self, measurementprocess: MeasurementProcess):

if diagonalizing_gates:
self._qubit_state.apply_operations(diagonalizing_gates)

results = self._measurement_lightning.probs(measurementprocess.wires.tolist())

if diagonalizing_gates:
Expand Down
18 changes: 16 additions & 2 deletions pennylane_lightning/lightning_gpu/_mpi_handler.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
# Copyright 2022-2023 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This module contains the :class:`~.LightningGPU_MPIHandler` class, a MPI handler to use LightningGPU device with multi-GPU on multi-node system.
"""

try:
# pylint: disable=no-name-in-module
Expand All @@ -20,7 +35,7 @@ class LightningGPU_MPIHandler():
MPI handler to use a GPU-backed Lightning device using NVIDIA cuQuantum SDK with parallel capabilities.
Use the MPI library is necessary to initialize different variables and methods to handle the data across nodes and perform checks for memory allocation on each device.
Use the MPI library is necessary to initialize different variables and methods to handle the data across nodes and perform checks for memory allocation on each device.
Args:
mpi (bool): declare if the device will use the MPI support.
Expand Down Expand Up @@ -52,7 +67,6 @@ def __init__(self,

if (mpi_buf_size > 0
and (mpi_buf_size & (mpi_buf_size - 1))):

raise ValueError(f"Unsupported mpi_buf_size value: {mpi_buf_size}. mpi_buf_size should be power of 2.")

# After check if all MPI parameter are ok
Expand Down
52 changes: 9 additions & 43 deletions pennylane_lightning/lightning_gpu/_state_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,11 @@
from pennylane.wires import Wires
from pennylane.measurements import MidMeasureMP
from pennylane.ops import Conditional
from pennylane import QuantumFunctionError, DeviceError
from pennylane import DeviceError

from pennylane_lightning.core._serialize import global_phase_diagonal
from pennylane_lightning.core._state_vector_base import LightningBaseStateVector

from ._measurements import LightningGPUMeasurements
from ._mpi_handler import LightningGPU_MPIHandler

gate_cache_needs_hash = (
Expand All @@ -73,14 +72,14 @@ class LightningGPUStateVector(LightningBaseStateVector):
device_name(string): state vector device name. Options: ["lightning.gpu"]
"""

def __init__(self, num_wires, dtype=np.complex128, device_name="lightning.gpu",
def __init__(self,
num_wires,
dtype=np.complex128,
device_name="lightning.gpu",
mpi_handler = None,
sync=True,
):

if device_name != "lightning.gpu":
raise DeviceError(f'The device name "{device_name}" is not a valid option.')

super().__init__(num_wires, dtype)

self._device_name = device_name
Expand Down Expand Up @@ -216,9 +215,10 @@ def _apply_state_vector(self, state, device_wires, use_async=False):
if isinstance(state, self._qubit_state.__class__):
raise DeviceError("LightningGPU does not support allocate external state_vector.")

state_data = allocate_aligned_array(state.size, np.dtype(self.dtype), True)
state.getState(state_data)
state = state_data
# TODO
# state_data = allocate_aligned_array(state.size, np.dtype(self.dtype), True)
# state.getState(state_data)
# state = state_data

state = self._asarray(state, dtype=self.dtype) # this operation on host
output_shape = [2] * self._num_local_wires
Expand Down Expand Up @@ -343,11 +343,6 @@ def _apply_lightning(
method = getattr(state, name, None)
wires = list(operation.wires)

# print("statevector: _apply_lightning: state:",state.__dir__)
# print("statevector: _apply_lightning: ops:",operation)
# print("statevector: _apply_lightning: name:",name)
# print("statevector: _apply_lightning: method:",method)

if isinstance(operation, Conditional):
if operation.meas_val.concretize(mid_measurements):
self._apply_lightning([operation.base])
Expand All @@ -373,13 +368,9 @@ def _apply_lightning(

r_dtype = np.float32 if self.dtype == np.complex64 else np.float64
param = [[r_dtype(operation.hash)]] if isinstance(operation, gate_cache_needs_hash) else []
# param = []
if len(mat) == 0:
raise ValueError("Unsupported operation")

# print("statevector: _apply_lightning: method:",method)
# print("statevector: _apply_lightning: mat:", mat)

self._qubit_state.apply(
name,
wires,
Expand All @@ -388,28 +379,3 @@ def _apply_lightning(
mat.ravel(order="C"), # inv = False: Matrix already in correct form;
) # Parameters can be ignored for explicit matrices; F-order for cuQuantum

# ----------------------------------------------------------
# method = getattr(state, "applyMatrix")
# # print("statevector: _apply_lightning: method:",method)
# # print("statevector: _apply_lightning: matrix:",qml.matrix(operation))
# # print("statevector: _apply_lightning: matrix:",operation.matrix)

# try:
# mat = qml.matrix(operation)
# except AttributeError: # pragma: no cover
# # To support older versions of PL
# mat = operation.matrix

# # mat = mat.ravel(order='C')
# # mat = mat.conjugate().transpose()

# print("statevector: _apply_lightning: mat:", mat)
# method(mat.ravel(order="C"), wires, False)

# # try:
# # method(mat, wires, False)
# # except AttributeError: # pragma: no cover
# # # To support older versions of PL
# # method(mat, wires, False)


8 changes: 4 additions & 4 deletions pennylane_lightning/lightning_gpu/lightning_gpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from ctypes.util import find_library
from importlib import util as imp_util
from pathlib import Path
from typing import Optional, Tuple, Callable, Union
from typing import Optional, Tuple Callable, Union

import numpy as np
import pennylane as qml
Expand Down Expand Up @@ -291,7 +291,7 @@ def __init__( # pylint: disable=too-many-arguments
)

# Set the attributes to call the LightningGPU classes
self._set_Lightning_classes()
self._set_lightning_classes()

# GPU specific options
self._dp = DevPool()
Expand All @@ -303,7 +303,6 @@ def __init__( # pylint: disable=too-many-arguments

self._num_local_wires = self._mpi_handler.num_local_wires

print("FSDX")
self._statevector = self.LightningStateVector(self.num_wires, dtype=c_dtype, mpi_handler=self._mpi_handler, sync=self._sync)


Expand All @@ -312,9 +311,10 @@ def name(self):
"""The name of the device."""
return "lightning.gpu"

def _set_Lightning_classes(self):
def _set_lightning_classes(self):
"""Load the LightningStateVector, LightningMeasurements, LightningAdjointJacobian as class attribute"""
self.LightningStateVector = LightningGPUStateVector
self.LightningMeasurements = LightningGPUMeasurements

def _setup_execution_config(self, config):
"""
Expand Down
27 changes: 2 additions & 25 deletions pennylane_lightning/lightning_kokkos/_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ def _process_single_shot(samples):

return tuple(processed)

print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: wires:",len(wires))
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: shot:",shots.total_shots)

try:
samples = self._measurement_lightning.generate_samples(
len(wires), shots.total_shots
Expand All @@ -105,36 +102,16 @@ def _process_single_shot(samples):
if str(e) != "probabilities contain NaN":
raise e
samples = qml.math.full((shots.total_shots, len(wires)), 0)

self._apply_diagonalizing_gates(mps, adjoint=True)
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: sample:")
unique, counts_uniq = np.unique(samples,axis=0, return_inverse=False, return_counts=True)
for val, c in zip(unique, counts_uniq):
print(val, c)
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: sample:",samples.shape)
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: sample:",samples.sum())

# if there is a shot vector, use the shots.bins generator to
# split samples w.r.t. the shots
processed_samples = []
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: shots.bins:", list(shots.bins()))
for lower, upper in shots.bins():
# result = _process_single_shot(samples[..., lower:upper, :])
tmp_sample = samples[..., lower:upper, :]
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: tmp_sample:")
unique, counts_uniq = np.unique(tmp_sample,axis=0, return_inverse=False, return_counts=True)
for val, c in zip(unique, counts_uniq):
print(val, c)

print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: tmp_sample", tmp_sample.shape)
print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: tmp_sample", tmp_sample.sum())
result = _process_single_shot(tmp_sample)

result = _process_single_shot(samples[..., lower:upper, :])
processed_samples.append(result)

print("Kokkos: Measurements: _measure_with_samples_diagonalizing_gates: result:", result)

print("I reach this place FDX")
return (
tuple(zip(*processed_samples)) if shots.has_partitioned_shots else processed_samples[0]
)
Expand Down
3 changes: 1 addition & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ def _device(wires, shots=None):
# General LightningStateVector fixture, for any number of wires.
@pytest.fixture(
scope="function",
# params=[np.complex64, np.complex128],
params=[np.complex128],
params=[np.complex64, np.complex128],
)
def lightning_sv(request):
def _statevector(num_wires):
Expand Down
16 changes: 2 additions & 14 deletions tests/lightning_qubit/test_measurements_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@


def get_hermitian_matrix(n):
np.random.seed(33)
H = np.random.rand(n, n) + 1.0j * np.random.rand(n, n)
return H + np.conj(H).T

Expand Down Expand Up @@ -409,7 +408,7 @@ def calculate_reference(tape, lightning_sv):
m = LightningMeasurements(statevector)
return m.measure_final_state(tape)

@flaky(max_runs=1)
@flaky(max_runs=2)
@pytest.mark.parametrize("shots", [None, 600_000, [790_000, 790_000]])
@pytest.mark.parametrize("measurement", [qml.expval, qml.probs, qml.var])
@pytest.mark.parametrize(
Expand Down Expand Up @@ -450,12 +449,6 @@ def test_single_return_value(self, shots, measurement, observable, lightning_sv,
pytest.skip(
f"Measurement of type {type(measurement).__name__} does not have a keyword argument 'wires'."
)

print()
print("shots:",shots)
print("measurement:",measurement)
print("observable:", observable)

rtol = 1.0e-2 # 1% of expected value as tolerance
if shots != None and measurement is qml.expval:
# Increase the number of shots
Expand All @@ -481,7 +474,6 @@ def test_single_return_value(self, shots, measurement, observable, lightning_sv,
tape = qml.tape.QuantumScript(ops, measurements, shots=shots)

statevector = lightning_sv(n_qubits)
# print("dtype:",statevector.dtype)
statevector = statevector.get_final_state(tape)
m = LightningMeasurements(statevector)

Expand All @@ -503,9 +495,6 @@ def test_single_return_value(self, shots, measurement, observable, lightning_sv,

expected = self.calculate_reference(tape, lightning_sv)

print("Result:")
print(f'expected: {expected}')
print(f' result: {result}')
# a few tests may fail in single precision, and hence we increase the tolerance
if shots is None:
assert np.allclose(result, expected, max(tol, 1.0e-4))
Expand All @@ -516,9 +505,8 @@ def test_single_return_value(self, shots, measurement, observable, lightning_sv,
# allclose -> absolute(a - b) <= (atol + rtol * absolute(b))
assert np.allclose(result, expected, rtol=rtol, atol=atol)

@flaky(max_runs=1)
@flaky(max_runs=10)
@pytest.mark.parametrize("shots", [None, 100_000, (90_000, 90_000)])
# @pytest.mark.parametrize("shots", [None, 100_000])
@pytest.mark.parametrize("measurement", [qml.expval, qml.probs, qml.var])
@pytest.mark.parametrize(
"obs0_",
Expand Down
2 changes: 0 additions & 2 deletions tests/lightning_qubit/test_state_vector_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
allow_module_level=True,
)

# if device_name == "lightning.gpu":
# pytest.skip("LGPU new API in WIP. Skipping.", allow_module_level=True)

if not LightningDevice._CPP_BINARY_AVAILABLE:
pytest.skip("No binary module found. Skipping.", allow_module_level=True)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
if not ld._CPP_BINARY_AVAILABLE:
pytest.skip("No binary module found. Skipping.", allow_module_level=True)

# if device_name == "lightning.gpu":
# pytest.skip("LGPU new API in WIP. Skipping.", allow_module_level=True)
if device_name == "lightning.gpu":
pytest.skip("LGPU new API in WIP. Skipping.", allow_module_level=True)


@pytest.mark.skipif(ld._new_API, reason="Old API required")
Expand Down

0 comments on commit 6627913

Please sign in to comment.