diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 78bc16cef0..a7625bb399 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,4 +1,4 @@ -# Release 0.24.0-dev +# Release 0.24.0 ### New features since last release @@ -8,7 +8,10 @@ * Add a new dispatch mechanism for future kernels. [(#291)](https://github.com/PennyLaneAI/pennylane-lightning/pull/291) -* Support qml.state() in vjp and Hamiltonian in adjoint jacobian. +* Add `IsingXY` gate operation. +[(#303)](https://github.com/PennyLaneAI/pennylane-lightning/pull/303) + +* Support `qml.state()` in vjp and Hamiltonian in adjoint jacobian. [(#294)](https://github.com/PennyLaneAI/pennylane-lightning/pull/294) ### Breaking changes @@ -21,6 +24,14 @@ ### Improvements +* Split matrix operations, refactor dispatch mechanisms, and add a benchmark suits. +[(#274)](https://github.com/PennyLaneAI/pennylane-lightning/pull/274) + +* Add native support for the calculation of sparse Hamiltonians' expectation values. +Sparse operations are offloaded to [Kokkos](https://github.com/kokkos/kokkos) and +[Kokkos-Kernels](https://github.com/kokkos/kokkos-kernels). +[(#283)](https://github.com/PennyLaneAI/pennylane-lightning/pull/283) + * Device `lightning.qubit` now accepts a datatype for a statevector. [(#290)](https://github.com/PennyLaneAI/pennylane-lightning/pull/290) @@ -29,12 +40,6 @@ dev1 = qml.device('lightning.qubit', wires=4, c_dtype=np.complex64) # for single dev2 = qml.device('lightning.qubit', wires=4, c_dtype=np.complex128) # for double precision ``` -* Split matrix operations, refactor dispatch mechanisms, and add a benchmark suits. -[(#274)](https://github.com/PennyLaneAI/pennylane-lightning/pull/274) - -* Add native support for the calculation of sparse Hamiltonians' expectation values. Sparse operations are offloaded to [Kokkos](https://github.com/kokkos/kokkos) and [Kokkos-Kernels](https://github.com/kokkos/kokkos-kernels). -[(#283)](https://github.com/PennyLaneAI/pennylane-lightning/pull/283) - ### Documentation * Use the centralized [Xanadu Sphinx Theme](https://github.com/XanaduAI/xanadu-sphinx-theme) @@ -44,13 +49,16 @@ dev2 = qml.device('lightning.qubit', wires=4, c_dtype=np.complex128) # for doubl ### Bug fixes * Fix the issue with using available `clang-format` version in format. -[#(288)](https://github.com/PennyLaneAI/pennylane-lightning/pull/288) +[(#288)](https://github.com/PennyLaneAI/pennylane-lightning/pull/288) + +* Fix a bug in the generator of `DoubleExcitationPlus`. +[(#298)](https://github.com/PennyLaneAI/pennylane-lightning/pull/298) ### Contributors This release contains contributions from (in alphabetical order): -Ali Asadi, Amintor Dusko, Chae-Yeun Park, Lee James O'Riordan, Mikhail Andrenkov +Mikhail Andrenkov, Ali Asadi, Amintor Dusko, Lee James O'Riordan, Chae-Yeun Park, and Shuli Shu --- diff --git a/.github/workflows/tests_linux.yml b/.github/workflows/tests_linux.yml index 72dfa7a2fe..6c15acd483 100644 --- a/.github/workflows/tests_linux.yml +++ b/.github/workflows/tests_linux.yml @@ -51,13 +51,6 @@ jobs: name: ubuntu-test-report path: Build/tests/results/report.xml - - name: Publish test results - uses: EnricoMi/publish-unit-test-result-action@v1 - if: always() - with: - check_name: Test Report (C++) on Ubuntu - files: Build/tests/results/report.xml - - name: Build and run unit tests for code Coverage run: | cmake pennylane_lightning/src -BBuildCov -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -DENABLE_COVERAGE=ON -DCMAKE_CXX_COMPILER="$(which g++-$GCC_VERSION)" @@ -111,13 +104,6 @@ jobs: name: ubuntu-test-report path: Build/tests/results/report.xml - - name: Publish test results - uses: EnricoMi/publish-unit-test-result-action@v1 - if: always() - with: - check_name: Test Report (C++) on Ubuntu - files: Build/tests/results/report.xml - - name: Build and run unit tests for code coverage run: | cmake pennylane_lightning/src -BBuildCov -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -DENABLE_COVERAGE=ON -DENABLE_BLAS=ON -DCMAKE_CXX_COMPILER="$(which g++-$GCC_VERSION)" @@ -184,7 +170,7 @@ jobs: uses: EnricoMi/publish-unit-test-result-action@v1 if: always() with: - check_name: Test Report (C++) on Ubuntu + check_name: Test Report (Linux, Kokkos, and Kokkos Kernels) on Ubuntu files: BuildCov/tests/results/report.xml cppbenchmarksuite: diff --git a/.github/workflows/wheel_macos_arm64.yml b/.github/workflows/wheel_macos_arm64.yml index d380d21b29..8a7b0faccf 100644 --- a/.github/workflows/wheel_macos_arm64.yml +++ b/.github/workflows/wheel_macos_arm64.yml @@ -10,6 +10,8 @@ on: env: CIBW_BUILD: 'cp37-* cp38-* cp39-* cp310-*' + ARCHS: 'arm64' + # MacOS specific build settings CIBW_BEFORE_ALL_MACOS: | brew uninstall --force oclint diff --git a/.gitignore b/.gitignore index 81d77afb50..6d0925ada6 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ doc/code/ *.so cpptests *.o - +.DS_Store .cache/* .vscode/* .ycm_extra_conf.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 6489877820..4e6762e010 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,7 @@ option(ENABLE_WARNINGS "Enable warnings" ON) option(ENABLE_NATIVE "Enable native CPU build tuning" OFF) option(ENABLE_AVX "Enable AVX support" OFF) option(ENABLE_OPENMP "Enable OpenMP" ON) -option(ENABLE_KOKKOS "Enable Kokkos" OFF) +option(ENABLE_KOKKOS "Enable Kokkos" ON) option(ENABLE_BLAS "Enable BLAS" OFF) # Other build options diff --git a/doc/requirements.txt b/doc/requirements.txt index d720a1dc78..33091bcf9f 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,6 +1,6 @@ breathe docutils==0.16 -exhale +exhale==0.3.1 graphviz pybind11 sphinx diff --git a/pennylane_lightning/_version.py b/pennylane_lightning/_version.py index 39fff18c09..6ff21ea0f5 100644 --- a/pennylane_lightning/_version.py +++ b/pennylane_lightning/_version.py @@ -16,4 +16,4 @@ Version number (major.minor.patch[-label]) """ -__version__ = "0.24.0-dev16" +__version__ = "0.24.0" diff --git a/pennylane_lightning/lightning_qubit.py b/pennylane_lightning/lightning_qubit.py index 71dc4d67ff..fc0b836823 100644 --- a/pennylane_lightning/lightning_qubit.py +++ b/pennylane_lightning/lightning_qubit.py @@ -224,7 +224,7 @@ def apply_lightning(self, state, operations): @staticmethod def _check_adjdiff_supported_measurements(measurements: List[MeasurementProcess]): - """Check whether given list of measurement is supported by adjoint_diff + """Check whether given list of measurement is supported by adjoint_diff. Args: measurements (List[MeasurementProcess]): a list of measurement processes to check. @@ -266,8 +266,7 @@ def _check_adjdiff_supported_operations(operations): observables, or operations by the Lightning adjoint differentiation method. Args: - tape (.QuantumTape): quantum tape to differentiate - + tape (.QuantumTape): quantum tape to differentiate. """ for op in operations: if op.num_params > 1 and not isinstance(op, Rot): @@ -423,6 +422,7 @@ def vjp(self, measurements, dy, starting_state=None, use_device_state=False): use_device_state (bool): use current device state to initialize. A forward pass of the same circuit should be the last thing the device has executed. If a ``starting_state`` is provided, that takes precedence. + Returns: The processing function required to compute the vector-Jacobian products of a tape. """ @@ -494,12 +494,12 @@ def batch_vjp( ): """Generate the processing function required to compute the vector-Jacobian products of a batch of tapes. + Args: tapes (Sequence[.QuantumTape]): sequence of quantum tapes to differentiate dys (Sequence[tensor_like]): Sequence of gradient-output vectors ``dy``. Must be the same length as ``tapes``. Each ``dy`` tensor should have shape matching the output shape of the corresponding tape. - Keyword Args: reduction (str): Determines how the vector-Jacobian products are returned. If ``append``, then the output of the function will be of the form ``List[tensor_like]``, with each element corresponding to the VJP of each @@ -509,6 +509,7 @@ def batch_vjp( use_device_state (bool): use current device state to initialize. A forward pass of the same circuit should be the last thing the device has executed. If a ``starting_state`` is provided, that takes precedence. + Returns: The processing function required to compute the vector-Jacobian products of a batch of tapes. """ diff --git a/pennylane_lightning/src/gates/Constant.hpp b/pennylane_lightning/src/gates/Constant.hpp index d9b26d8052..c80a38acf4 100644 --- a/pennylane_lightning/src/gates/Constant.hpp +++ b/pennylane_lightning/src/gates/Constant.hpp @@ -116,6 +116,8 @@ namespace Pennylane::Gates::Constant { "GeneratorCRZ"}, std::pair{GeneratorOperation::IsingXX, "GeneratorIsingXX"}, + std::pair{GeneratorOperation::IsingXY, + "GeneratorIsingXY"}, std::pair{GeneratorOperation::IsingYY, "GeneratorIsingYY"}, std::pair{GeneratorOperation::IsingZZ, @@ -203,6 +205,7 @@ namespace Pennylane::Gates::Constant { std::pair{GeneratorOperation::RY, 1}, std::pair{GeneratorOperation::RZ, 1}, std::pair{GeneratorOperation::IsingXX, 2}, + std::pair{GeneratorOperation::IsingXY, 2}, std::pair{GeneratorOperation::IsingYY, 2}, std::pair{GeneratorOperation::IsingZZ, 2}, std::pair{GeneratorOperation::CRX, 2}, diff --git a/pennylane_lightning/src/gates/GateOperation.hpp b/pennylane_lightning/src/gates/GateOperation.hpp index 25ecf41657..8f590bd7b8 100644 --- a/pennylane_lightning/src/gates/GateOperation.hpp +++ b/pennylane_lightning/src/gates/GateOperation.hpp @@ -80,6 +80,7 @@ enum class GeneratorOperation : uint32_t { RY, RZ, IsingXX, + IsingXY, IsingYY, IsingZZ, CRX, diff --git a/pennylane_lightning/src/gates/OpToMemberFuncPtr.hpp b/pennylane_lightning/src/gates/OpToMemberFuncPtr.hpp index e385dcc588..4dbb10e15e 100644 --- a/pennylane_lightning/src/gates/OpToMemberFuncPtr.hpp +++ b/pennylane_lightning/src/gates/OpToMemberFuncPtr.hpp @@ -298,6 +298,12 @@ struct GeneratorOpToMemberFuncPtr; }; template +struct GeneratorOpToMemberFuncPtr { + constexpr static auto value = + &GateImplementation::template applyGeneratorIsingXY; +}; +template struct GeneratorOpToMemberFuncPtr { constexpr static auto value = diff --git a/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsLM.hpp b/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsLM.hpp index 4e88a72214..9a49bf0bcd 100644 --- a/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsLM.hpp +++ b/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsLM.hpp @@ -115,6 +115,7 @@ class GateImplementationsLM : public PauliGenerator { GeneratorOperation::CRY, GeneratorOperation::CRZ, GeneratorOperation::IsingXX, + GeneratorOperation::IsingXY, GeneratorOperation::IsingYY, GeneratorOperation::IsingZZ, GeneratorOperation::ControlledPhaseShift, @@ -1111,6 +1112,34 @@ class GateImplementationsLM : public PauliGenerator { return -static_cast(0.5); } + template + [[nodiscard]] static auto + applyGeneratorIsingXY(std::complex *arr, size_t num_qubits, + const std::vector &wires, + [[maybe_unused]] bool adj) -> PrecisionT { + PL_ASSERT(wires.size() == 2); + const size_t rev_wire0 = num_qubits - wires[1] - 1; + const size_t rev_wire1 = num_qubits - wires[0] - 1; // Control qubit + const size_t rev_wire0_shift = static_cast(1U) << rev_wire0; + const size_t rev_wire1_shift = static_cast(1U) << rev_wire1; + const auto [parity_high, parity_middle, parity_low] = + revWireParity(rev_wire0, rev_wire1); + + for (size_t k = 0; k < Util::exp2(num_qubits - 2); k++) { + const size_t i00 = ((k << 2U) & parity_high) | + ((k << 1U) & parity_middle) | (k & parity_low); + const size_t i01 = i00 | rev_wire0_shift; + const size_t i10 = i00 | rev_wire1_shift; + const size_t i11 = i00 | rev_wire0_shift | rev_wire1_shift; + + std::swap(arr[i10], arr[i01]); + arr[i00] = std::complex{0.0, 0.0}; + arr[i11] = std::complex{0.0, 0.0}; + } + // NOLINTNEXTLINE(readability-magic-numbers) + return static_cast(0.5); + } + template [[nodiscard]] static auto applyGeneratorIsingYY(std::complex *arr, size_t num_qubits, @@ -1320,10 +1349,10 @@ class GateImplementationsLM : public PauliGenerator { for (size_t k = 0; k < Util::exp2(num_qubits); k++) { arr[k] *= static_cast( - 2 * int(std::popcount(k & wires_parity) % 2) - 1); + 1 - 2 * int(std::popcount(k & wires_parity) % 2)); } // NOLINTNEXTLINE(readability-magic-numbers) - return static_cast(0.5); + return -static_cast(0.5); } }; } // namespace Pennylane::Gates diff --git a/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsPI.hpp b/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsPI.hpp index 2f75c2bfa5..1b800308d1 100644 --- a/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsPI.hpp +++ b/pennylane_lightning/src/gates/cpu_kernels/GateImplementationsPI.hpp @@ -94,6 +94,7 @@ class GateImplementationsPI : public PauliGenerator { GeneratorOperation::RZ, GeneratorOperation::PhaseShift, GeneratorOperation::IsingXX, + GeneratorOperation::IsingXY, GeneratorOperation::IsingYY, GeneratorOperation::IsingZZ, GeneratorOperation::CRX, @@ -922,6 +923,26 @@ class GateImplementationsPI : public PauliGenerator { return -static_cast(0.5); } + template + [[nodiscard]] static auto + applyGeneratorIsingXY(std::complex *arr, size_t num_qubits, + const std::vector &wires, + [[maybe_unused]] bool adj) -> PrecisionT { + PL_ASSERT(wires.size() == 2); + const auto [indices, externalIndices] = GateIndices(wires, num_qubits); + + for (const size_t &externalIndex : externalIndices) { + std::complex *shiftedState = arr + externalIndex; + + std::swap(shiftedState[indices[2]], shiftedState[indices[1]]); + shiftedState[indices[0]] = std::complex{0.0, 0.0}; + shiftedState[indices[3]] = std::complex{0.0, 0.0}; + } + + // NOLINTNEXTLINE(readability-magic-numbers) + return static_cast(0.5); + } + template [[nodiscard]] static auto applyGeneratorIsingYY(std::complex *arr, size_t num_qubits, diff --git a/pennylane_lightning/src/simulator/KernelMap.cpp b/pennylane_lightning/src/simulator/KernelMap.cpp index e1179874a7..b313b4869d 100644 --- a/pennylane_lightning/src/simulator/KernelMap.cpp +++ b/pennylane_lightning/src/simulator/KernelMap.cpp @@ -167,6 +167,9 @@ int assignDefaultKernelsForGeneratorOp() { instance.assignKernelForOp(GeneratorOperation::IsingXX, all_threading, all_memory_model, all_qubit_numbers, KernelType::LM); + instance.assignKernelForOp(GeneratorOperation::IsingXY, all_threading, + all_memory_model, all_qubit_numbers, + KernelType::LM); instance.assignKernelForOp(GeneratorOperation::IsingYY, all_threading, all_memory_model, all_qubit_numbers, KernelType::LM); diff --git a/pennylane_lightning/src/tests/Test_OpToMemberFuncPtr.cpp b/pennylane_lightning/src/tests/Test_OpToMemberFuncPtr.cpp index 0e1211f8e2..e459974ead 100644 --- a/pennylane_lightning/src/tests/Test_OpToMemberFuncPtr.cpp +++ b/pennylane_lightning/src/tests/Test_OpToMemberFuncPtr.cpp @@ -146,6 +146,7 @@ class DummyImplementation { PENNYLANE_TESTS_DEFINE_GENERATOR_OP(RY) PENNYLANE_TESTS_DEFINE_GENERATOR_OP(RZ) PENNYLANE_TESTS_DEFINE_GENERATOR_OP(IsingXX) + PENNYLANE_TESTS_DEFINE_GENERATOR_OP(IsingXY) PENNYLANE_TESTS_DEFINE_GENERATOR_OP(IsingYY) PENNYLANE_TESTS_DEFINE_GENERATOR_OP(IsingZZ) PENNYLANE_TESTS_DEFINE_GENERATOR_OP(CRX) diff --git a/setup.py b/setup.py index c4c9d685f8..d62e652152 100644 --- a/setup.py +++ b/setup.py @@ -77,6 +77,11 @@ def build_extension(self, ext: CMakeExtension): # Add more platform dependent options if platform.system() == "Darwin": + #To support ARM64 + if os.getenv('ARCHS') == "arm64": + configure_args += ["-DCMAKE_CXX_FLAGS='-target arm64-apple-macos11'"] + else: + configure_args += [] # Disable OpenMP in M1 Macs if os.environ.get("USE_OMP"): configure_args += [] diff --git a/tests/test_adjoint_jacobian.py b/tests/test_adjoint_jacobian.py index 2d0daee7e4..22c1bbaf6f 100644 --- a/tests/test_adjoint_jacobian.py +++ b/tests/test_adjoint_jacobian.py @@ -875,6 +875,7 @@ def circuit_ansatz(params, wires): # # qml.PauliRot(params[12], "XXYZ", wires=[wires[0], wires[1], wires[2], wires[3]]) qml.CPhase(params[12], wires=[wires[3], wires[2]]) qml.IsingXX(params[13], wires=[wires[1], wires[0]]) + qml.IsingXY(params[14], wires=[wires[3], wires[2]]) qml.IsingYY(params[14], wires=[wires[3], wires[2]]) qml.IsingZZ(params[14], wires=[wires[2], wires[1]]) qml.U1(params[15], wires=wires[0]) diff --git a/tests/test_array.py b/tests/test_array.py index b154ac2a4d..297a6e2b4e 100644 --- a/tests/test_array.py +++ b/tests/test_array.py @@ -15,9 +15,7 @@ Unit tests for the :mod:`pennylane_lightning.LightningQubit` device. """ import numpy as np -import pennylane as qml import pytest -from pennylane import DeviceError from pennylane_lightning.lightning_qubit import CPP_BINARY_AVAILABLE diff --git a/tests/test_serialize.py b/tests/test_serialize.py index 3dc121cde0..25a976c83e 100644 --- a/tests/test_serialize.py +++ b/tests/test_serialize.py @@ -14,9 +14,7 @@ """ Unit tests for the serialization helper functions """ -from asyncio import set_child_watcher import pennylane as qml -from pennylane import numpy as qnp import numpy as np import pennylane_lightning