From 81870b7bc427ce2362e29a64d77f33aa80062104 Mon Sep 17 00:00:00 2001 From: Shuli Shu <31480676+multiphaseCFD@users.noreply.github.com> Date: Tue, 28 May 2024 11:18:03 -0400 Subject: [PATCH] Add NonParametric & Parametric Gates support to Lightning.Tensor (#718) * init commit * Auto update version from '0.36.0-dev44' to '0.36.0-dev46' * typo fix * fix last blank line error * fix codecov warnings * fix CI & change ctor interface * remove unused methods * tidy up code and add more unit tests * add testhelper & tidy up code * fix typo * set PL_TENSOR in the root cmakelists * add more tests for tensor classes * make format * fix sitesExtents_ init & add mpscutn tests * only test cutnmps cpp layer * further tidy up code * update MPS ctor * refactor MPSCutn to allow easy TN extension * move methods to CutnBase class & rename maxextent * update docstring * turn on all ci unit tests * fix codefactor complaining * add changelog * Trigger CI * quick fix for getFreeMemorySize * fix based on some comments * size_t->std::size_t * set computeState() as protected & make format * copy ctor -> std::move * safer store for ptr to sitesExtents and tensor * std::vector ->std::vector * update base on comments * update docstring * update memory set * make format * size_t->std::size_t for ->GENERATE * Auto update version from '0.36.0-dev46' to '0.36.0-dev48' * On-Board Lightning Linux workflows (that are run on PRs) to large runners based on label (#700) * Try on-boarding to large runner * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Remove usage of runner.os in job name * Fix invalid runs-on * Remove usage of runner.os in job name * Trigger CI * Fix inputs.run-on for build&cache kokkos * Trigger CI * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' --------- Co-authored-by: ringo-but-quantum Co-authored-by: Vincent Michaud-Rioux * Port PR #705 changes (#711) * port PR #705 changes * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Update pennylane_lightning/lightning_qubit/lightning_qubit.py Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Trigger CIs * fix CodeFactor fail * fix CodeFactor fail * fix CodeFactor fail * Auto update version from '0.36.0-dev46' to '0.36.0-dev47' --------- Co-authored-by: ringo-but-quantum Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * fix naming comments and drop initHelper_() * move MPSStatus to MPS class & update docstrings * udpate tensornetbase ctor * Auto update version from '0.36.0-dev48' to '0.36.0-dev49' * enum to c++ style * update unit tests * update class name cutn->TNCuda * Auto update version from '0.36.0-dev49' to '0.37.0-dev2' * Syncing master with V0.36.0 branch (#715) * Update Changelog * update release candidate version * run agains pennylane rc * update relese cadidate version * Increase tolerance for a flaky test (test_single_return_value) * Update `LightningBaseFallBack` to raise an error instead of falling back to default.qubit (#689) * Initial commit. * Update changelog * Auto update version * trigger ci * Unused import. * Auto update version * trigger ci * Fix imports. * Auto update version * Fix LightningException * make format * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.36.0-dev35' to '0.36.0-dev36' * Auto update version from '0.36.0-dev36' to '0.36.0-dev37' * Make python -m pip install consistent. * Fix ImportError * Auto update version from '0.36.0-dev37' to '0.36.0-dev38' * --force-reinstall * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Remove --force-reinstall * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Spec CMAKE_CXX_COMPILER * Fix quotes. * Remove quotes * Hardcode g++-11 * use env.COMPILER * which g++ * Revert * Downgrade pip * Pin libomp. * Revert wheel_linux * Upload artifacts. * Comment upload trigger * Install pip==23 * Revert libomp * try testing outside cibuildwheel * yum install devtools * yum install devtools * Do not install python * Revert changes * Don't editable install. * Not edit install * Not edit install * Fix cov path * Explicit mcm tests path * Fix qml.QuantumFunctionError error messages. --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: AmintorDusko * trigger CIs * Introduce pytest-splits (#696) * Try update lightning CI paths * Auto update version * Update kokkos tests to trigger on changes to pl core * Auto update version * Split tests_linux.yml into cpp/python. * Auto update version from '0.36.0-dev36' to '0.36.0-dev38' * Split GPU tests into cpp/python. * Split MPI-GPU tests into cpp/python. * Fix LGPU triggers. * Remove python tests from LGPU-C++. * Remove upload-to-codecov-linux-cpp from LGPUMPI tests. * Rename test workflows. * Update changelog. * Change group names. * Use paths-ignore to simplify workflow paths * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Fix test names. * you may only define one of `paths` and `paths-ignore` for a single event * Fix formatting * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Change to paths-ignore in no-bin tests. * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * trigger ci * Change error message. * Split build/test jobs. * Revert pennylane_lightning/lightning_kokkos/lightning_kokkos.py * Fix setup.py command * Comment workflows * Comment pull_request: * Copy wheels to github.workspace /wheels * SKIP_COMPILATION=True * Revert SKIP_COMPILATION=True * Remove duplicate python actions. * Split LQ-test into 5 groups. * Update requirements-dev.txt * 2 groups * 1 group * 7 groups * Refactor LKokos tests * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Fix cache id * Fix needs * Remove all builds * put back CMAKE_PREFIX_PATH * install fake lightning * Fix compat paths * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Revert changes. * Update changelog * trigger ci * build_and_cache_Kokkos_linux.yml not concurrent. * Remove C++ tests from compat tests (skipped anyways). * Use ${{ github.ref }}-${{ github.event }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }} for concurrency groups. * PL_BACKEND: ${{ matrix.pl_backend }} * Update changelog * Install wheel package. * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Install scipy wheel in one place. * Comment job triggers. * Add LK[cpu] est durations. * trigger ci * Use sha independent keys. * trigger ci * build_and_cache_Kokkos * Change LK keys * ls -l * Install version nonce * Do not skip comp. * Trade ref for sha in key * Install after PL * ref ==> sha * Reorder * Try LQ workflows. * Use actions/setup-python * Revert triggers. * Provide correct cov path. * Revert pennylane_lightning/core/src/utils/config.h * LK uses 5 groups. * Restore wheels to main * main/wheels * Revert cache paths * Fix ls -l * fail-on-cache-miss: true * Introduce env.GITHUB_WORKSPACE * Use artifacts * Fix paths * No ls -l * Download to github.workspace * fix wheel name * WHEEL_NAME * Add blas. * Use outputs. * Send wheel name * Fix artifact name * Fix name * Use WHEEL_NAME var * artifacts kokkos * fix wheel name * Restore bins. * Clean up * Split Linux CPU python tests into 2. * Fix compat workflows. * Split format and tidy workflows. * fix lkcpu * fix concurrency group * Do not use editable installs. * Split full kokkos tests except unitary_correct * Upload LK test durations. * duration-paths * Unique test_durations * Unique test_durations * Unique test_durations * Fix path * Update python_lightning_kokkos_test_durations * Remove obsolete all and SERIAL tests. * Update changelog * Creating the `LightningTensor` device class based on the new API (#671) * empty commit (triggering CI) * Auto update version * Definition of the two front-end classes * adding the `lightning_tensor` string to the supported backends in `setup.py` * adding `__init__.py` file to directly import the `lightning_tensor` device class * re-naming file * Auto update version * Creating the first prototype of initial MPS state tensor using `quimb` * providing the `backend`, `method` parameters and making `wires` optional * Changing names and structure * Auto update version * adding method required by the new device API design * Auto update version * using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in `quimb` * taking some further inputs from the new device API * Perhaps decided the overall structure of `LIghtningTensor` * Auto update version * adding docs to methods * temporary changes so that `pylint` does not complain at this stage * running `isort` * re-running formatter after `isort` * re-running formatter after `isort` * Applying suggested formatting change from CI * adding tmp unit tests * Adding `quimb` in `requirements.txt` * runing `isort` on mps test * removing `quimb` from requirement and deleting unit tests for `lightning.tensor` * Auto update version * re-inserting unit tests with an additional `yml` file * running isort on quimb test * changing name of yml file * preventing error in import * updating yml file * inserting `quimb` package in requirements-dev * strange error with `quimb` * strange error with `quimb` * specifying scipy version * removing installation of scipy from yml file * removing the new `yml` file * testing if tests are tested * Covering all lines in tests * forgot final line for formatter * Python formatter on CI complaints * covering missing lines * formatter on CI complaints * Trying not to skip test if Cpp is enabled * skipping tests if Cpp is enabled * removing the only line not covered by tests so far * Auto update version * Applying suggestions from code review and making the `state` attribute private (new API design) * Python formatter * removing params from `QuimbMPS` * Auto update version * removing `**kwargs` from `QuimbMPS` * removing unnecessary param at this stage * covering test line * formatter... * removing param description * Making `pylint` happy * forgot new arg in test * Updating base class and `preprocess` function * Updating `LightningTensor` class with new names from more advanced PR * Auto update version * Auto update version * Triggering CI * Auto update version * Trying to remove pin from `quimb` in `requirements.dev` * Auto update version * Auto update version * Removing infos on derivatives and using config options to pass parameters to interface * Usual `pylint` failures * Trying to solve formatting errors * typo in docstring * Sunday update: improved docstrings and structure * Removing method that was supposed to be in next PR * removing old TODO comment * Removing changes from the `setup.py` file * restoring previous format to `setup.py` * Auto update version from '0.36.0-dev34' to '0.36.0-dev41' * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * Removing kwargs as suggested from code review * Addressing comments from CR * Skipping tests if CPP binary is available * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Restoring name in changelog (?) * Increasing time limit for Python tests * Applying suggestions from code review --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum * Increase tolerance for a flaky test (test_single_return_value) (#703) * update dev version * increase tolerance * update changelog * trigger CIs * Auto update version from '0.36.0-dev44' to '0.36.0-dev45' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Remove LTensor stuff * Update changelog * Revert requirements-dev.txt * trigger ci * Update python_lightning_kokkos_test_durations * Restore 'all' tests in tests_lkcuda_python.yml * Fix durations paths. * Try --splitting-algorithm=least_duration * Try no -n auto lkcpu tests * One last test. --------- Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update changelog (#706) * Use wire order specified on instantiation (#705) * use map wires instead of map_to_standard_wires * oops * Update .github/CHANGELOG.md * black * Trigger CIs * add test * black on tests * Update .github/CHANGELOG.md --------- Co-authored-by: AmintorDusko Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update wire order support for probabilities (#707) * Begin expansion of probs tests * Update tests to exhaustively compute probs with wires * Update all tests in LQ Meas to use CHECK instead of REQUIRES for better signal of failures * Add Jet Permuter * Add noisy functionality * Fix permutation ordering * Update changelog * Fix wrong ordering in probs tests * Add recommendation from apache flink to purge azure dirs * Forbid out of order indices for probs with LK and LG in CPP layer * Remove MSFT tools from GH Actions * Just try to remove dotnet * List opt hostedtoolcache * Remove packages from /opt/hostedtoolcache * Fix missing test hit * Forbid and remove broken tests from LK probs ordering * Fix clang-tidy isms * Ensure libopenblas is not broken from failed apt pull with dev * Appease GH Action * Full remove GH action modifier step due to unexplained failures * Add bidreictional wire validation for LGPU CPP layer * Clang-tidy warning fix * Appease CT * Update JET license agreement * Sync version * pacify CodeFactor * make CodeFactor ignore all JET code * trigger ci * trigger ci * build wheels for test * remove Win LKokkos upload-pypi [skip-ci] * [skip ci] * trigger wheels CIs with Release event * update version * fix upload wheels artifact for release * target pennylane master * Version bump CHANGELOG * Auto update version from '' to '0.36.0-dev48' * version bump to dev0 * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update version * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update pennylane_lightning/core/_version.py --------- Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan Co-authored-by: Vincent Michaud-Rioux * Update Linux wheels to use manylinux_2_28 (#667) * update version * update gcc and containers for linux_x86_64 * trigger CIs * test Engine * try removing podman * try alternative path for docker * y * priviledged container * aarch64 * build wheels * dnf->yum * install dependencies (apt) * update container * update and build ppc64le wheels * update and build x86_64_cuda wheels * update config-manager * add install dnf-utils * Auto update version * update dev version * move dnf-utils * set cuda repository to AlmaLinux * make gcc 12 * Auto update version * trigger ci * upload artifacts * Update .github/workflows/wheel_linux_x86_64.yml Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update .github/workflows/wheel_linux_x86_64.yml Co-authored-by: Raul Torres <138264735+rauletorresc@users.noreply.github.com> * Auto update version from '0.36.0-dev29' to '0.36.0-dev36' * fix source for linux_x86_64_cuda * Auto update version from '0.36.0-dev37' to '0.36.0-dev36' * Update Changelog * update release candidate version * run agains pennylane rc * update relese cadidate version * Increase tolerance for a flaky test (test_single_return_value) * format * Update `LightningBaseFallBack` to raise an error instead of falling back to default.qubit (#689) * Initial commit. * Update changelog * Auto update version * trigger ci * Unused import. * Auto update version * trigger ci * Fix imports. * Auto update version * Fix LightningException * make format * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.36.0-dev35' to '0.36.0-dev36' * Auto update version from '0.36.0-dev36' to '0.36.0-dev37' * Make python -m pip install consistent. * Fix ImportError * Auto update version from '0.36.0-dev37' to '0.36.0-dev38' * --force-reinstall * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Remove --force-reinstall * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Spec CMAKE_CXX_COMPILER * Fix quotes. * Remove quotes * Hardcode g++-11 * use env.COMPILER * which g++ * Revert * Downgrade pip * Pin libomp. * Revert wheel_linux * Upload artifacts. * Comment upload trigger * Install pip==23 * Revert libomp * try testing outside cibuildwheel * yum install devtools * yum install devtools * Do not install python * Revert changes * Don't editable install. * Not edit install * Not edit install * Fix cov path * Explicit mcm tests path * Fix qml.QuantumFunctionError error messages. --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: AmintorDusko * trigger CIs * Introduce pytest-splits (#696) * Try update lightning CI paths * Auto update version * Update kokkos tests to trigger on changes to pl core * Auto update version * Split tests_linux.yml into cpp/python. * Auto update version from '0.36.0-dev36' to '0.36.0-dev38' * Split GPU tests into cpp/python. * Split MPI-GPU tests into cpp/python. * Fix LGPU triggers. * Remove python tests from LGPU-C++. * Remove upload-to-codecov-linux-cpp from LGPUMPI tests. * Rename test workflows. * Update changelog. * Change group names. * Use paths-ignore to simplify workflow paths * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Fix test names. * you may only define one of `paths` and `paths-ignore` for a single event * Fix formatting * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Change to paths-ignore in no-bin tests. * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * trigger ci * Change error message. * Split build/test jobs. * Revert pennylane_lightning/lightning_kokkos/lightning_kokkos.py * Fix setup.py command * Comment workflows * Comment pull_request: * Copy wheels to github.workspace /wheels * SKIP_COMPILATION=True * Revert SKIP_COMPILATION=True * Remove duplicate python actions. * Split LQ-test into 5 groups. * Update requirements-dev.txt * 2 groups * 1 group * 7 groups * Refactor LKokos tests * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Fix cache id * Fix needs * Remove all builds * put back CMAKE_PREFIX_PATH * install fake lightning * Fix compat paths * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Revert changes. * Update changelog * trigger ci * build_and_cache_Kokkos_linux.yml not concurrent. * Remove C++ tests from compat tests (skipped anyways). * Use ${{ github.ref }}-${{ github.event }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }} for concurrency groups. * PL_BACKEND: ${{ matrix.pl_backend }} * Update changelog * Install wheel package. * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Install scipy wheel in one place. * Comment job triggers. * Add LK[cpu] est durations. * trigger ci * Use sha independent keys. * trigger ci * build_and_cache_Kokkos * Change LK keys * ls -l * Install version nonce * Do not skip comp. * Trade ref for sha in key * Install after PL * ref ==> sha * Reorder * Try LQ workflows. * Use actions/setup-python * Revert triggers. * Provide correct cov path. * Revert pennylane_lightning/core/src/utils/config.h * LK uses 5 groups. * Restore wheels to main * main/wheels * Revert cache paths * Fix ls -l * fail-on-cache-miss: true * Introduce env.GITHUB_WORKSPACE * Use artifacts * Fix paths * No ls -l * Download to github.workspace * fix wheel name * WHEEL_NAME * Add blas. * Use outputs. * Send wheel name * Fix artifact name * Fix name * Use WHEEL_NAME var * artifacts kokkos * fix wheel name * Restore bins. * Clean up * Split Linux CPU python tests into 2. * Fix compat workflows. * Split format and tidy workflows. * fix lkcpu * fix concurrency group * Do not use editable installs. * Split full kokkos tests except unitary_correct * Upload LK test durations. * duration-paths * Unique test_durations * Unique test_durations * Unique test_durations * Fix path * Update python_lightning_kokkos_test_durations * Remove obsolete all and SERIAL tests. * Update changelog * Creating the `LightningTensor` device class based on the new API (#671) * empty commit (triggering CI) * Auto update version * Definition of the two front-end classes * adding the `lightning_tensor` string to the supported backends in `setup.py` * adding `__init__.py` file to directly import the `lightning_tensor` device class * re-naming file * Auto update version * Creating the first prototype of initial MPS state tensor using `quimb` * providing the `backend`, `method` parameters and making `wires` optional * Changing names and structure * Auto update version * adding method required by the new device API design * Auto update version * using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in `quimb` * taking some further inputs from the new device API * Perhaps decided the overall structure of `LIghtningTensor` * Auto update version * adding docs to methods * temporary changes so that `pylint` does not complain at this stage * running `isort` * re-running formatter after `isort` * re-running formatter after `isort` * Applying suggested formatting change from CI * adding tmp unit tests * Adding `quimb` in `requirements.txt` * runing `isort` on mps test * removing `quimb` from requirement and deleting unit tests for `lightning.tensor` * Auto update version * re-inserting unit tests with an additional `yml` file * running isort on quimb test * changing name of yml file * preventing error in import * updating yml file * inserting `quimb` package in requirements-dev * strange error with `quimb` * strange error with `quimb` * specifying scipy version * removing installation of scipy from yml file * removing the new `yml` file * testing if tests are tested * Covering all lines in tests * forgot final line for formatter * Python formatter on CI complaints * covering missing lines * formatter on CI complaints * Trying not to skip test if Cpp is enabled * skipping tests if Cpp is enabled * removing the only line not covered by tests so far * Auto update version * Applying suggestions from code review and making the `state` attribute private (new API design) * Python formatter * removing params from `QuimbMPS` * Auto update version * removing `**kwargs` from `QuimbMPS` * removing unnecessary param at this stage * covering test line * formatter... * removing param description * Making `pylint` happy * forgot new arg in test * Updating base class and `preprocess` function * Updating `LightningTensor` class with new names from more advanced PR * Auto update version * Auto update version * Triggering CI * Auto update version * Trying to remove pin from `quimb` in `requirements.dev` * Auto update version * Auto update version * Removing infos on derivatives and using config options to pass parameters to interface * Usual `pylint` failures * Trying to solve formatting errors * typo in docstring * Sunday update: improved docstrings and structure * Removing method that was supposed to be in next PR * removing old TODO comment * Removing changes from the `setup.py` file * restoring previous format to `setup.py` * Auto update version from '0.36.0-dev34' to '0.36.0-dev41' * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * Removing kwargs as suggested from code review * Addressing comments from CR * Skipping tests if CPP binary is available * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Restoring name in changelog (?) * Increasing time limit for Python tests * Applying suggestions from code review --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum * Increase tolerance for a flaky test (test_single_return_value) (#703) * update dev version * increase tolerance * update changelog * trigger CIs * Auto update version from '0.36.0-dev44' to '0.36.0-dev45' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Remove LTensor stuff * Update changelog * Revert requirements-dev.txt * trigger ci * Update python_lightning_kokkos_test_durations * Restore 'all' tests in tests_lkcuda_python.yml * Fix durations paths. * Try --splitting-algorithm=least_duration * Try no -n auto lkcpu tests * One last test. --------- Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update changelog (#706) * Use wire order specified on instantiation (#705) * use map wires instead of map_to_standard_wires * oops * Update .github/CHANGELOG.md * black * Trigger CIs * add test * black on tests * Update .github/CHANGELOG.md --------- Co-authored-by: AmintorDusko Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update wire order support for probabilities (#707) * Begin expansion of probs tests * Update tests to exhaustively compute probs with wires * Update all tests in LQ Meas to use CHECK instead of REQUIRES for better signal of failures * Add Jet Permuter * Add noisy functionality * Fix permutation ordering * Update changelog * Fix wrong ordering in probs tests * Add recommendation from apache flink to purge azure dirs * Forbid out of order indices for probs with LK and LG in CPP layer * Remove MSFT tools from GH Actions * Just try to remove dotnet * List opt hostedtoolcache * Remove packages from /opt/hostedtoolcache * Fix missing test hit * Forbid and remove broken tests from LK probs ordering * Fix clang-tidy isms * Ensure libopenblas is not broken from failed apt pull with dev * Appease GH Action * Full remove GH action modifier step due to unexplained failures * Add bidreictional wire validation for LGPU CPP layer * Clang-tidy warning fix * Appease CT * Update JET license agreement * Sync version * pacify CodeFactor * make CodeFactor ignore all JET code * trigger ci * trigger ci * build wheels for test * remove Win LKokkos upload-pypi [skip-ci] * [skip ci] * trigger wheels CIs with Release event * update version * fix upload wheels artifact for release * target pennylane master * Version bump CHANGELOG * Auto update version from '' to '0.36.0-dev48' * version bump to dev0 * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update version * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update pennylane_lightning/core/_version.py * update changelog * Update .github/workflows/wheel_linux_aarch64.yml * Update .github/workflows/wheel_linux_ppc64le.yml --------- Co-authored-by: Dev version update bot Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Raul Torres <138264735+rauletorresc@users.noreply.github.com> Co-authored-by: ringo-but-quantum Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan Co-authored-by: Vincent Michaud-Rioux * change filename * make format * Auto update version from '0.37.0-dev2' to '0.37.0-dev3' * change path name * Accelerate CI parallelizing over OMP configs (#712) * Update Changelog * update release candidate version * run agains pennylane rc * update relese cadidate version * Increase tolerance for a flaky test (test_single_return_value) * Update `LightningBaseFallBack` to raise an error instead of falling back to default.qubit (#689) * Initial commit. * Update changelog * Auto update version * trigger ci * Unused import. * Auto update version * trigger ci * Fix imports. * Auto update version * Fix LightningException * make format * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.36.0-dev35' to '0.36.0-dev36' * Auto update version from '0.36.0-dev36' to '0.36.0-dev37' * Make python -m pip install consistent. * Fix ImportError * Auto update version from '0.36.0-dev37' to '0.36.0-dev38' * --force-reinstall * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Remove --force-reinstall * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Spec CMAKE_CXX_COMPILER * Fix quotes. * Remove quotes * Hardcode g++-11 * use env.COMPILER * which g++ * Revert * Downgrade pip * Pin libomp. * Revert wheel_linux * Upload artifacts. * Comment upload trigger * Install pip==23 * Revert libomp * try testing outside cibuildwheel * yum install devtools * yum install devtools * Do not install python * Revert changes * Don't editable install. * Not edit install * Not edit install * Fix cov path * Explicit mcm tests path * Fix qml.QuantumFunctionError error messages. --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: AmintorDusko * trigger CIs * Introduce pytest-splits (#696) * Try update lightning CI paths * Auto update version * Update kokkos tests to trigger on changes to pl core * Auto update version * Split tests_linux.yml into cpp/python. * Auto update version from '0.36.0-dev36' to '0.36.0-dev38' * Split GPU tests into cpp/python. * Split MPI-GPU tests into cpp/python. * Fix LGPU triggers. * Remove python tests from LGPU-C++. * Remove upload-to-codecov-linux-cpp from LGPUMPI tests. * Rename test workflows. * Update changelog. * Change group names. * Use paths-ignore to simplify workflow paths * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Fix test names. * you may only define one of `paths` and `paths-ignore` for a single event * Fix formatting * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Change to paths-ignore in no-bin tests. * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * trigger ci * Change error message. * Split build/test jobs. * Revert pennylane_lightning/lightning_kokkos/lightning_kokkos.py * Fix setup.py command * Comment workflows * Comment pull_request: * Copy wheels to github.workspace /wheels * SKIP_COMPILATION=True * Revert SKIP_COMPILATION=True * Remove duplicate python actions. * Split LQ-test into 5 groups. * Update requirements-dev.txt * 2 groups * 1 group * 7 groups * Refactor LKokos tests * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Fix cache id * Fix needs * Remove all builds * put back CMAKE_PREFIX_PATH * install fake lightning * Fix compat paths * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Revert changes. * Update changelog * trigger ci * build_and_cache_Kokkos_linux.yml not concurrent. * Remove C++ tests from compat tests (skipped anyways). * Use ${{ github.ref }}-${{ github.event }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }} for concurrency groups. * PL_BACKEND: ${{ matrix.pl_backend }} * Update changelog * Install wheel package. * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Install scipy wheel in one place. * Comment job triggers. * Add LK[cpu] est durations. * trigger ci * Use sha independent keys. * trigger ci * build_and_cache_Kokkos * Change LK keys * ls -l * Install version nonce * Do not skip comp. * Trade ref for sha in key * Install after PL * ref ==> sha * Reorder * Try LQ workflows. * Use actions/setup-python * Revert triggers. * Provide correct cov path. * Revert pennylane_lightning/core/src/utils/config.h * LK uses 5 groups. * Restore wheels to main * main/wheels * Revert cache paths * Fix ls -l * fail-on-cache-miss: true * Introduce env.GITHUB_WORKSPACE * Use artifacts * Fix paths * No ls -l * Download to github.workspace * fix wheel name * WHEEL_NAME * Add blas. * Use outputs. * Send wheel name * Fix artifact name * Fix name * Use WHEEL_NAME var * artifacts kokkos * fix wheel name * Restore bins. * Clean up * Split Linux CPU python tests into 2. * Fix compat workflows. * Split format and tidy workflows. * fix lkcpu * fix concurrency group * Do not use editable installs. * Split full kokkos tests except unitary_correct * Upload LK test durations. * duration-paths * Unique test_durations * Unique test_durations * Unique test_durations * Fix path * Update python_lightning_kokkos_test_durations * Remove obsolete all and SERIAL tests. * Update changelog * Creating the `LightningTensor` device class based on the new API (#671) * empty commit (triggering CI) * Auto update version * Definition of the two front-end classes * adding the `lightning_tensor` string to the supported backends in `setup.py` * adding `__init__.py` file to directly import the `lightning_tensor` device class * re-naming file * Auto update version * Creating the first prototype of initial MPS state tensor using `quimb` * providing the `backend`, `method` parameters and making `wires` optional * Changing names and structure * Auto update version * adding method required by the new device API design * Auto update version * using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in `quimb` * taking some further inputs from the new device API * Perhaps decided the overall structure of `LIghtningTensor` * Auto update version * adding docs to methods * temporary changes so that `pylint` does not complain at this stage * running `isort` * re-running formatter after `isort` * re-running formatter after `isort` * Applying suggested formatting change from CI * adding tmp unit tests * Adding `quimb` in `requirements.txt` * runing `isort` on mps test * removing `quimb` from requirement and deleting unit tests for `lightning.tensor` * Auto update version * re-inserting unit tests with an additional `yml` file * running isort on quimb test * changing name of yml file * preventing error in import * updating yml file * inserting `quimb` package in requirements-dev * strange error with `quimb` * strange error with `quimb` * specifying scipy version * removing installation of scipy from yml file * removing the new `yml` file * testing if tests are tested * Covering all lines in tests * forgot final line for formatter * Python formatter on CI complaints * covering missing lines * formatter on CI complaints * Trying not to skip test if Cpp is enabled * skipping tests if Cpp is enabled * removing the only line not covered by tests so far * Auto update version * Applying suggestions from code review and making the `state` attribute private (new API design) * Python formatter * removing params from `QuimbMPS` * Auto update version * removing `**kwargs` from `QuimbMPS` * removing unnecessary param at this stage * covering test line * formatter... * removing param description * Making `pylint` happy * forgot new arg in test * Updating base class and `preprocess` function * Updating `LightningTensor` class with new names from more advanced PR * Auto update version * Auto update version * Triggering CI * Auto update version * Trying to remove pin from `quimb` in `requirements.dev` * Auto update version * Auto update version * Removing infos on derivatives and using config options to pass parameters to interface * Usual `pylint` failures * Trying to solve formatting errors * typo in docstring * Sunday update: improved docstrings and structure * Removing method that was supposed to be in next PR * removing old TODO comment * Removing changes from the `setup.py` file * restoring previous format to `setup.py` * Auto update version from '0.36.0-dev34' to '0.36.0-dev41' * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * Removing kwargs as suggested from code review * Addressing comments from CR * Skipping tests if CPP binary is available * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Restoring name in changelog (?) * Increasing time limit for Python tests * Applying suggestions from code review --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum * Increase tolerance for a flaky test (test_single_return_value) (#703) * update dev version * increase tolerance * update changelog * trigger CIs * Auto update version from '0.36.0-dev44' to '0.36.0-dev45' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Remove LTensor stuff * Update changelog * Revert requirements-dev.txt * trigger ci * Update python_lightning_kokkos_test_durations * Restore 'all' tests in tests_lkcuda_python.yml * Fix durations paths. * Try --splitting-algorithm=least_duration * Try no -n auto lkcpu tests * One last test. --------- Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update changelog (#706) * Use wire order specified on instantiation (#705) * use map wires instead of map_to_standard_wires * oops * Update .github/CHANGELOG.md * black * Trigger CIs * add test * black on tests * Update .github/CHANGELOG.md --------- Co-authored-by: AmintorDusko Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update wire order support for probabilities (#707) * Begin expansion of probs tests * Update tests to exhaustively compute probs with wires * Update all tests in LQ Meas to use CHECK instead of REQUIRES for better signal of failures * Add Jet Permuter * Add noisy functionality * Fix permutation ordering * Update changelog * Fix wrong ordering in probs tests * Add recommendation from apache flink to purge azure dirs * Forbid out of order indices for probs with LK and LG in CPP layer * Remove MSFT tools from GH Actions * Just try to remove dotnet * List opt hostedtoolcache * Remove packages from /opt/hostedtoolcache * Fix missing test hit * Forbid and remove broken tests from LK probs ordering * Fix clang-tidy isms * Ensure libopenblas is not broken from failed apt pull with dev * Appease GH Action * Full remove GH action modifier step due to unexplained failures * Add bidreictional wire validation for LGPU CPP layer * Clang-tidy warning fix * Appease CT * Update JET license agreement * Sync version * pacify CodeFactor * make CodeFactor ignore all JET code * trigger ci * trigger ci * Split OMP builds using matrix. * trigger ci * Ignore .github but not self. * Fix cd.. * Fix path * Update changelog [skip ci] * Revert changes to reqs.txt * Auto update version from '0.37.0-dev0' to '0.37.0-dev2' * Auto update version from '0.37.0-dev1' to '0.37.0-dev2' * Update .github/CHANGELOG.md Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update .github/CHANGELOG.md Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> --------- Co-authored-by: AmintorDusko Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan * Initial commit * add changelog * Auto update version from '0.37.0-dev3' to '0.37.0-dev4' * refactor TNCudaGateCache & add appendGateTensorOperator * add tests for 1 & 2 qubits gates * add unit tests for 3 qubit gates & update compute state * tidy up getDataVector() and remove once call limitation * tidy up code * fix multiple reset()/setbasisstate() & resolve comments * add gates sub_directory to build * add initial unit tests for parametric gates * add ising gates * update version * add controlledPhaseShift * add all the parametric gates besides multiRZ * Test unsupported gate * allow passing matrix on host to device as operator * add changelog * col-major for LGPU and row-major for LTN * Trigger CI * Auto update version from '0.37.0-dev9' to '0.37.0-dev10' * tidy up code * Auto update version from '0.37.0-dev10' to '0.37.0-dev14' * Add `MPSTNCuda` class (#704) * init commit * Auto update version from '0.36.0-dev44' to '0.36.0-dev46' * typo fix * fix last blank line error * fix codecov warnings * fix CI & change ctor interface * remove unused methods * tidy up code and add more unit tests * add testhelper & tidy up code * fix typo * set PL_TENSOR in the root cmakelists * add more tests for tensor classes * make format * fix sitesExtents_ init & add mpscutn tests * only test cutnmps cpp layer * further tidy up code * update MPS ctor * refactor MPSCutn to allow easy TN extension * move methods to CutnBase class & rename maxextent * update docstring * turn on all ci unit tests * fix codefactor complaining * add changelog * Trigger CI * quick fix for getFreeMemorySize * fix based on some comments * size_t->std::size_t * set computeState() as protected & make format * copy ctor -> std::move * safer store for ptr to sitesExtents and tensor * std::vector ->std::vector * update base on comments * update docstring * update memory set * make format * size_t->std::size_t for ->GENERATE * Auto update version from '0.36.0-dev46' to '0.36.0-dev48' * On-Board Lightning Linux workflows (that are run on PRs) to large runners based on label (#700) * Try on-boarding to large runner * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Remove usage of runner.os in job name * Fix invalid runs-on * Remove usage of runner.os in job name * Trigger CI * Fix inputs.run-on for build&cache kokkos * Trigger CI * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' --------- Co-authored-by: ringo-but-quantum Co-authored-by: Vincent Michaud-Rioux * Port PR #705 changes (#711) * port PR #705 changes * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Update pennylane_lightning/lightning_qubit/lightning_qubit.py Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Trigger CIs * fix CodeFactor fail * fix CodeFactor fail * fix CodeFactor fail * Auto update version from '0.36.0-dev46' to '0.36.0-dev47' --------- Co-authored-by: ringo-but-quantum Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * fix naming comments and drop initHelper_() * move MPSStatus to MPS class & update docstrings * udpate tensornetbase ctor * Auto update version from '0.36.0-dev48' to '0.36.0-dev49' * enum to c++ style * update unit tests * update class name cutn->TNCuda * Auto update version from '0.36.0-dev49' to '0.37.0-dev2' * Syncing master with V0.36.0 branch (#715) * Update Changelog * update release candidate version * run agains pennylane rc * update relese cadidate version * Increase tolerance for a flaky test (test_single_return_value) * Update `LightningBaseFallBack` to raise an error instead of falling back to default.qubit (#689) * Initial commit. * Update changelog * Auto update version * trigger ci * Unused import. * Auto update version * trigger ci * Fix imports. * Auto update version * Fix LightningException * make format * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.36.0-dev35' to '0.36.0-dev36' * Auto update version from '0.36.0-dev36' to '0.36.0-dev37' * Make python -m pip install consistent. * Fix ImportError * Auto update version from '0.36.0-dev37' to '0.36.0-dev38' * --force-reinstall * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Remove --force-reinstall * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Spec CMAKE_CXX_COMPILER * Fix quotes. * Remove quotes * Hardcode g++-11 * use env.COMPILER * which g++ * Revert * Downgrade pip * Pin libomp. * Revert wheel_linux * Upload artifacts. * Comment upload trigger * Install pip==23 * Revert libomp * try testing outside cibuildwheel * yum install devtools * yum install devtools * Do not install python * Revert changes * Don't editable install. * Not edit install * Not edit install * Fix cov path * Explicit mcm tests path * Fix qml.QuantumFunctionError error messages. --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: AmintorDusko * trigger CIs * Introduce pytest-splits (#696) * Try update lightning CI paths * Auto update version * Update kokkos tests to trigger on changes to pl core * Auto update version * Split tests_linux.yml into cpp/python. * Auto update version from '0.36.0-dev36' to '0.36.0-dev38' * Split GPU tests into cpp/python. * Split MPI-GPU tests into cpp/python. * Fix LGPU triggers. * Remove python tests from LGPU-C++. * Remove upload-to-codecov-linux-cpp from LGPUMPI tests. * Rename test workflows. * Update changelog. * Change group names. * Use paths-ignore to simplify workflow paths * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Fix test names. * you may only define one of `paths` and `paths-ignore` for a single event * Fix formatting * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Change to paths-ignore in no-bin tests. * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * trigger ci * Change error message. * Split build/test jobs. * Revert pennylane_lightning/lightning_kokkos/lightning_kokkos.py * Fix setup.py command * Comment workflows * Comment pull_request: * Copy wheels to github.workspace /wheels * SKIP_COMPILATION=True * Revert SKIP_COMPILATION=True * Remove duplicate python actions. * Split LQ-test into 5 groups. * Update requirements-dev.txt * 2 groups * 1 group * 7 groups * Refactor LKokos tests * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Fix cache id * Fix needs * Remove all builds * put back CMAKE_PREFIX_PATH * install fake lightning * Fix compat paths * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Revert changes. * Update changelog * trigger ci * build_and_cache_Kokkos_linux.yml not concurrent. * Remove C++ tests from compat tests (skipped anyways). * Use ${{ github.ref }}-${{ github.event }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }} for concurrency groups. * PL_BACKEND: ${{ matrix.pl_backend }} * Update changelog * Install wheel package. * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Install scipy wheel in one place. * Comment job triggers. * Add LK[cpu] est durations. * trigger ci * Use sha independent keys. * trigger ci * build_and_cache_Kokkos * Change LK keys * ls -l * Install version nonce * Do not skip comp. * Trade ref for sha in key * Install after PL * ref ==> sha * Reorder * Try LQ workflows. * Use actions/setup-python * Revert triggers. * Provide correct cov path. * Revert pennylane_lightning/core/src/utils/config.h * LK uses 5 groups. * Restore wheels to main * main/wheels * Revert cache paths * Fix ls -l * fail-on-cache-miss: true * Introduce env.GITHUB_WORKSPACE * Use artifacts * Fix paths * No ls -l * Download to github.workspace * fix wheel name * WHEEL_NAME * Add blas. * Use outputs. * Send wheel name * Fix artifact name * Fix name * Use WHEEL_NAME var * artifacts kokkos * fix wheel name * Restore bins. * Clean up * Split Linux CPU python tests into 2. * Fix compat workflows. * Split format and tidy workflows. * fix lkcpu * fix concurrency group * Do not use editable installs. * Split full kokkos tests except unitary_correct * Upload LK test durations. * duration-paths * Unique test_durations * Unique test_durations * Unique test_durations * Fix path * Update python_lightning_kokkos_test_durations * Remove obsolete all and SERIAL tests. * Update changelog * Creating the `LightningTensor` device class based on the new API (#671) * empty commit (triggering CI) * Auto update version * Definition of the two front-end classes * adding the `lightning_tensor` string to the supported backends in `setup.py` * adding `__init__.py` file to directly import the `lightning_tensor` device class * re-naming file * Auto update version * Creating the first prototype of initial MPS state tensor using `quimb` * providing the `backend`, `method` parameters and making `wires` optional * Changing names and structure * Auto update version * adding method required by the new device API design * Auto update version * using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in `quimb` * taking some further inputs from the new device API * Perhaps decided the overall structure of `LIghtningTensor` * Auto update version * adding docs to methods * temporary changes so that `pylint` does not complain at this stage * running `isort` * re-running formatter after `isort` * re-running formatter after `isort` * Applying suggested formatting change from CI * adding tmp unit tests * Adding `quimb` in `requirements.txt` * runing `isort` on mps test * removing `quimb` from requirement and deleting unit tests for `lightning.tensor` * Auto update version * re-inserting unit tests with an additional `yml` file * running isort on quimb test * changing name of yml file * preventing error in import * updating yml file * inserting `quimb` package in requirements-dev * strange error with `quimb` * strange error with `quimb` * specifying scipy version * removing installation of scipy from yml file * removing the new `yml` file * testing if tests are tested * Covering all lines in tests * forgot final line for formatter * Python formatter on CI complaints * covering missing lines * formatter on CI complaints * Trying not to skip test if Cpp is enabled * skipping tests if Cpp is enabled * removing the only line not covered by tests so far * Auto update version * Applying suggestions from code review and making the `state` attribute private (new API design) * Python formatter * removing params from `QuimbMPS` * Auto update version * removing `**kwargs` from `QuimbMPS` * removing unnecessary param at this stage * covering test line * formatter... * removing param description * Making `pylint` happy * forgot new arg in test * Updating base class and `preprocess` function * Updating `LightningTensor` class with new names from more advanced PR * Auto update version * Auto update version * Triggering CI * Auto update version * Trying to remove pin from `quimb` in `requirements.dev` * Auto update version * Auto update version * Removing infos on derivatives and using config options to pass parameters to interface * Usual `pylint` failures * Trying to solve formatting errors * typo in docstring * Sunday update: improved docstrings and structure * Removing method that was supposed to be in next PR * removing old TODO comment * Removing changes from the `setup.py` file * restoring previous format to `setup.py` * Auto update version from '0.36.0-dev34' to '0.36.0-dev41' * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * Removing kwargs as suggested from code review * Addressing comments from CR * Skipping tests if CPP binary is available * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Restoring name in changelog (?) * Increasing time limit for Python tests * Applying suggestions from code review --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum * Increase tolerance for a flaky test (test_single_return_value) (#703) * update dev version * increase tolerance * update changelog * trigger CIs * Auto update version from '0.36.0-dev44' to '0.36.0-dev45' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Remove LTensor stuff * Update changelog * Revert requirements-dev.txt * trigger ci * Update python_lightning_kokkos_test_durations * Restore 'all' tests in tests_lkcuda_python.yml * Fix durations paths. * Try --splitting-algorithm=least_duration * Try no -n auto lkcpu tests * One last test. --------- Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update changelog (#706) * Use wire order specified on instantiation (#705) * use map wires instead of map_to_standard_wires * oops * Update .github/CHANGELOG.md * black * Trigger CIs * add test * black on tests * Update .github/CHANGELOG.md --------- Co-authored-by: AmintorDusko Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update wire order support for probabilities (#707) * Begin expansion of probs tests * Update tests to exhaustively compute probs with wires * Update all tests in LQ Meas to use CHECK instead of REQUIRES for better signal of failures * Add Jet Permuter * Add noisy functionality * Fix permutation ordering * Update changelog * Fix wrong ordering in probs tests * Add recommendation from apache flink to purge azure dirs * Forbid out of order indices for probs with LK and LG in CPP layer * Remove MSFT tools from GH Actions * Just try to remove dotnet * List opt hostedtoolcache * Remove packages from /opt/hostedtoolcache * Fix missing test hit * Forbid and remove broken tests from LK probs ordering * Fix clang-tidy isms * Ensure libopenblas is not broken from failed apt pull with dev * Appease GH Action * Full remove GH action modifier step due to unexplained failures * Add bidreictional wire validation for LGPU CPP layer * Clang-tidy warning fix * Appease CT * Update JET license agreement * Sync version * pacify CodeFactor * make CodeFactor ignore all JET code * trigger ci * trigger ci * build wheels for test * remove Win LKokkos upload-pypi [skip-ci] * [skip ci] * trigger wheels CIs with Release event * update version * fix upload wheels artifact for release * target pennylane master * Version bump CHANGELOG * Auto update version from '' to '0.36.0-dev48' * version bump to dev0 * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update version * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update pennylane_lightning/core/_version.py --------- Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan Co-authored-by: Vincent Michaud-Rioux * Update Linux wheels to use manylinux_2_28 (#667) * update version * update gcc and containers for linux_x86_64 * trigger CIs * test Engine * try removing podman * try alternative path for docker * y * priviledged container * aarch64 * build wheels * dnf->yum * install dependencies (apt) * update container * update and build ppc64le wheels * update and build x86_64_cuda wheels * update config-manager * add install dnf-utils * Auto update version * update dev version * move dnf-utils * set cuda repository to AlmaLinux * make gcc 12 * Auto update version * trigger ci * upload artifacts * Update .github/workflows/wheel_linux_x86_64.yml Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update .github/workflows/wheel_linux_x86_64.yml Co-authored-by: Raul Torres <138264735+rauletorresc@users.noreply.github.com> * Auto update version from '0.36.0-dev29' to '0.36.0-dev36' * fix source for linux_x86_64_cuda * Auto update version from '0.36.0-dev37' to '0.36.0-dev36' * Update Changelog * update release candidate version * run agains pennylane rc * update relese cadidate version * Increase tolerance for a flaky test (test_single_return_value) * format * Update `LightningBaseFallBack` to raise an error instead of falling back to default.qubit (#689) * Initial commit. * Update changelog * Auto update version * trigger ci * Unused import. * Auto update version * trigger ci * Fix imports. * Auto update version * Fix LightningException * make format * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.36.0-dev35' to '0.36.0-dev36' * Auto update version from '0.36.0-dev36' to '0.36.0-dev37' * Make python -m pip install consistent. * Fix ImportError * Auto update version from '0.36.0-dev37' to '0.36.0-dev38' * --force-reinstall * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Remove --force-reinstall * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Spec CMAKE_CXX_COMPILER * Fix quotes. * Remove quotes * Hardcode g++-11 * use env.COMPILER * which g++ * Revert * Downgrade pip * Pin libomp. * Revert wheel_linux * Upload artifacts. * Comment upload trigger * Install pip==23 * Revert libomp * try testing outside cibuildwheel * yum install devtools * yum install devtools * Do not install python * Revert changes * Don't editable install. * Not edit install * Not edit install * Fix cov path * Explicit mcm tests path * Fix qml.QuantumFunctionError error messages. --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: AmintorDusko * trigger CIs * Introduce pytest-splits (#696) * Try update lightning CI paths * Auto update version * Update kokkos tests to trigger on changes to pl core * Auto update version * Split tests_linux.yml into cpp/python. * Auto update version from '0.36.0-dev36' to '0.36.0-dev38' * Split GPU tests into cpp/python. * Split MPI-GPU tests into cpp/python. * Fix LGPU triggers. * Remove python tests from LGPU-C++. * Remove upload-to-codecov-linux-cpp from LGPUMPI tests. * Rename test workflows. * Update changelog. * Change group names. * Use paths-ignore to simplify workflow paths * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Fix test names. * you may only define one of `paths` and `paths-ignore` for a single event * Fix formatting * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Change to paths-ignore in no-bin tests. * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * trigger ci * Change error message. * Split build/test jobs. * Revert pennylane_lightning/lightning_kokkos/lightning_kokkos.py * Fix setup.py command * Comment workflows * Comment pull_request: * Copy wheels to github.workspace /wheels * SKIP_COMPILATION=True * Revert SKIP_COMPILATION=True * Remove duplicate python actions. * Split LQ-test into 5 groups. * Update requirements-dev.txt * 2 groups * 1 group * 7 groups * Refactor LKokos tests * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Fix cache id * Fix needs * Remove all builds * put back CMAKE_PREFIX_PATH * install fake lightning * Fix compat paths * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Revert changes. * Update changelog * trigger ci * build_and_cache_Kokkos_linux.yml not concurrent. * Remove C++ tests from compat tests (skipped anyways). * Use ${{ github.ref }}-${{ github.event }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }} for concurrency groups. * PL_BACKEND: ${{ matrix.pl_backend }} * Update changelog * Install wheel package. * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Install scipy wheel in one place. * Comment job triggers. * Add LK[cpu] est durations. * trigger ci * Use sha independent keys. * trigger ci * build_and_cache_Kokkos * Change LK keys * ls -l * Install version nonce * Do not skip comp. * Trade ref for sha in key * Install after PL * ref ==> sha * Reorder * Try LQ workflows. * Use actions/setup-python * Revert triggers. * Provide correct cov path. * Revert pennylane_lightning/core/src/utils/config.h * LK uses 5 groups. * Restore wheels to main * main/wheels * Revert cache paths * Fix ls -l * fail-on-cache-miss: true * Introduce env.GITHUB_WORKSPACE * Use artifacts * Fix paths * No ls -l * Download to github.workspace * fix wheel name * WHEEL_NAME * Add blas. * Use outputs. * Send wheel name * Fix artifact name * Fix name * Use WHEEL_NAME var * artifacts kokkos * fix wheel name * Restore bins. * Clean up * Split Linux CPU python tests into 2. * Fix compat workflows. * Split format and tidy workflows. * fix lkcpu * fix concurrency group * Do not use editable installs. * Split full kokkos tests except unitary_correct * Upload LK test durations. * duration-paths * Unique test_durations * Unique test_durations * Unique test_durations * Fix path * Update python_lightning_kokkos_test_durations * Remove obsolete all and SERIAL tests. * Update changelog * Creating the `LightningTensor` device class based on the new API (#671) * empty commit (triggering CI) * Auto update version * Definition of the two front-end classes * adding the `lightning_tensor` string to the supported backends in `setup.py` * adding `__init__.py` file to directly import the `lightning_tensor` device class * re-naming file * Auto update version * Creating the first prototype of initial MPS state tensor using `quimb` * providing the `backend`, `method` parameters and making `wires` optional * Changing names and structure * Auto update version * adding method required by the new device API design * Auto update version * using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in `quimb` * taking some further inputs from the new device API * Perhaps decided the overall structure of `LIghtningTensor` * Auto update version * adding docs to methods * temporary changes so that `pylint` does not complain at this stage * running `isort` * re-running formatter after `isort` * re-running formatter after `isort` * Applying suggested formatting change from CI * adding tmp unit tests * Adding `quimb` in `requirements.txt` * runing `isort` on mps test * removing `quimb` from requirement and deleting unit tests for `lightning.tensor` * Auto update version * re-inserting unit tests with an additional `yml` file * running isort on quimb test * changing name of yml file * preventing error in import * updating yml file * inserting `quimb` package in requirements-dev * strange error with `quimb` * strange error with `quimb` * specifying scipy version * removing installation of scipy from yml file * removing the new `yml` file * testing if tests are tested * Covering all lines in tests * forgot final line for formatter * Python formatter on CI complaints * covering missing lines * formatter on CI complaints * Trying not to skip test if Cpp is enabled * skipping tests if Cpp is enabled * removing the only line not covered by tests so far * Auto update version * Applying suggestions from code review and making the `state` attribute private (new API design) * Python formatter * removing params from `QuimbMPS` * Auto update version * removing `**kwargs` from `QuimbMPS` * removing unnecessary param at this stage * covering test line * formatter... * removing param description * Making `pylint` happy * forgot new arg in test * Updating base class and `preprocess` function * Updating `LightningTensor` class with new names from more advanced PR * Auto update version * Auto update version * Triggering CI * Auto update version * Trying to remove pin from `quimb` in `requirements.dev` * Auto update version * Auto update version * Removing infos on derivatives and using config options to pass parameters to interface * Usual `pylint` failures * Trying to solve formatting errors * typo in docstring * Sunday update: improved docstrings and structure * Removing method that was supposed to be in next PR * removing old TODO comment * Removing changes from the `setup.py` file * restoring previous format to `setup.py` * Auto update version from '0.36.0-dev34' to '0.36.0-dev41' * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * Removing kwargs as suggested from code review * Addressing comments from CR * Skipping tests if CPP binary is available * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Restoring name in changelog (?) * Increasing time limit for Python tests * Applying suggestions from code review --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum * Increase tolerance for a flaky test (test_single_return_value) (#703) * update dev version * increase tolerance * update changelog * trigger CIs * Auto update version from '0.36.0-dev44' to '0.36.0-dev45' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Remove LTensor stuff * Update changelog * Revert requirements-dev.txt * trigger ci * Update python_lightning_kokkos_test_durations * Restore 'all' tests in tests_lkcuda_python.yml * Fix durations paths. * Try --splitting-algorithm=least_duration * Try no -n auto lkcpu tests * One last test. --------- Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update changelog (#706) * Use wire order specified on instantiation (#705) * use map wires instead of map_to_standard_wires * oops * Update .github/CHANGELOG.md * black * Trigger CIs * add test * black on tests * Update .github/CHANGELOG.md --------- Co-authored-by: AmintorDusko Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update wire order support for probabilities (#707) * Begin expansion of probs tests * Update tests to exhaustively compute probs with wires * Update all tests in LQ Meas to use CHECK instead of REQUIRES for better signal of failures * Add Jet Permuter * Add noisy functionality * Fix permutation ordering * Update changelog * Fix wrong ordering in probs tests * Add recommendation from apache flink to purge azure dirs * Forbid out of order indices for probs with LK and LG in CPP layer * Remove MSFT tools from GH Actions * Just try to remove dotnet * List opt hostedtoolcache * Remove packages from /opt/hostedtoolcache * Fix missing test hit * Forbid and remove broken tests from LK probs ordering * Fix clang-tidy isms * Ensure libopenblas is not broken from failed apt pull with dev * Appease GH Action * Full remove GH action modifier step due to unexplained failures * Add bidreictional wire validation for LGPU CPP layer * Clang-tidy warning fix * Appease CT * Update JET license agreement * Sync version * pacify CodeFactor * make CodeFactor ignore all JET code * trigger ci * trigger ci * build wheels for test * remove Win LKokkos upload-pypi [skip-ci] * [skip ci] * trigger wheels CIs with Release event * update version * fix upload wheels artifact for release * target pennylane master * Version bump CHANGELOG * Auto update version from '' to '0.36.0-dev48' * version bump to dev0 * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update version * Auto update version from '0.37.0-dev0' to '0.36.0-dev48' * Update pennylane_lightning/core/_version.py * update changelog * Update .github/workflows/wheel_linux_aarch64.yml * Update .github/workflows/wheel_linux_ppc64le.yml --------- Co-authored-by: Dev version update bot Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Raul Torres <138264735+rauletorresc@users.noreply.github.com> Co-authored-by: ringo-but-quantum Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan Co-authored-by: Vincent Michaud-Rioux * change filename * make format * Auto update version from '0.37.0-dev2' to '0.37.0-dev3' * change path name * Accelerate CI parallelizing over OMP configs (#712) * Update Changelog * update release candidate version * run agains pennylane rc * update relese cadidate version * Increase tolerance for a flaky test (test_single_return_value) * Update `LightningBaseFallBack` to raise an error instead of falling back to default.qubit (#689) * Initial commit. * Update changelog * Auto update version * trigger ci * Unused import. * Auto update version * trigger ci * Fix imports. * Auto update version * Fix LightningException * make format * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.36.0-dev35' to '0.36.0-dev36' * Auto update version from '0.36.0-dev36' to '0.36.0-dev37' * Make python -m pip install consistent. * Fix ImportError * Auto update version from '0.36.0-dev37' to '0.36.0-dev38' * --force-reinstall * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Remove --force-reinstall * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Spec CMAKE_CXX_COMPILER * Fix quotes. * Remove quotes * Hardcode g++-11 * use env.COMPILER * which g++ * Revert * Downgrade pip * Pin libomp. * Revert wheel_linux * Upload artifacts. * Comment upload trigger * Install pip==23 * Revert libomp * try testing outside cibuildwheel * yum install devtools * yum install devtools * Do not install python * Revert changes * Don't editable install. * Not edit install * Not edit install * Fix cov path * Explicit mcm tests path * Fix qml.QuantumFunctionError error messages. --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: AmintorDusko * trigger CIs * Introduce pytest-splits (#696) * Try update lightning CI paths * Auto update version * Update kokkos tests to trigger on changes to pl core * Auto update version * Split tests_linux.yml into cpp/python. * Auto update version from '0.36.0-dev36' to '0.36.0-dev38' * Split GPU tests into cpp/python. * Split MPI-GPU tests into cpp/python. * Fix LGPU triggers. * Remove python tests from LGPU-C++. * Remove upload-to-codecov-linux-cpp from LGPUMPI tests. * Rename test workflows. * Update changelog. * Change group names. * Use paths-ignore to simplify workflow paths * Auto update version from '0.36.0-dev38' to '0.36.0-dev39' * Fix test names. * you may only define one of `paths` and `paths-ignore` for a single event * Fix formatting * Auto update version from '0.36.0-dev39' to '0.36.0-dev40' * Change to paths-ignore in no-bin tests. * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * trigger ci * Change error message. * Split build/test jobs. * Revert pennylane_lightning/lightning_kokkos/lightning_kokkos.py * Fix setup.py command * Comment workflows * Comment pull_request: * Copy wheels to github.workspace /wheels * SKIP_COMPILATION=True * Revert SKIP_COMPILATION=True * Remove duplicate python actions. * Split LQ-test into 5 groups. * Update requirements-dev.txt * 2 groups * 1 group * 7 groups * Refactor LKokos tests * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Fix cache id * Fix needs * Remove all builds * put back CMAKE_PREFIX_PATH * install fake lightning * Fix compat paths * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Revert changes. * Update changelog * trigger ci * build_and_cache_Kokkos_linux.yml not concurrent. * Remove C++ tests from compat tests (skipped anyways). * Use ${{ github.ref }}-${{ github.event }}-${{ inputs.lightning-version }}-${{ inputs.pennylane-version }} for concurrency groups. * PL_BACKEND: ${{ matrix.pl_backend }} * Update changelog * Install wheel package. * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Install scipy wheel in one place. * Comment job triggers. * Add LK[cpu] est durations. * trigger ci * Use sha independent keys. * trigger ci * build_and_cache_Kokkos * Change LK keys * ls -l * Install version nonce * Do not skip comp. * Trade ref for sha in key * Install after PL * ref ==> sha * Reorder * Try LQ workflows. * Use actions/setup-python * Revert triggers. * Provide correct cov path. * Revert pennylane_lightning/core/src/utils/config.h * LK uses 5 groups. * Restore wheels to main * main/wheels * Revert cache paths * Fix ls -l * fail-on-cache-miss: true * Introduce env.GITHUB_WORKSPACE * Use artifacts * Fix paths * No ls -l * Download to github.workspace * fix wheel name * WHEEL_NAME * Add blas. * Use outputs. * Send wheel name * Fix artifact name * Fix name * Use WHEEL_NAME var * artifacts kokkos * fix wheel name * Restore bins. * Clean up * Split Linux CPU python tests into 2. * Fix compat workflows. * Split format and tidy workflows. * fix lkcpu * fix concurrency group * Do not use editable installs. * Split full kokkos tests except unitary_correct * Upload LK test durations. * duration-paths * Unique test_durations * Unique test_durations * Unique test_durations * Fix path * Update python_lightning_kokkos_test_durations * Remove obsolete all and SERIAL tests. * Update changelog * Creating the `LightningTensor` device class based on the new API (#671) * empty commit (triggering CI) * Auto update version * Definition of the two front-end classes * adding the `lightning_tensor` string to the supported backends in `setup.py` * adding `__init__.py` file to directly import the `lightning_tensor` device class * re-naming file * Auto update version * Creating the first prototype of initial MPS state tensor using `quimb` * providing the `backend`, `method` parameters and making `wires` optional * Changing names and structure * Auto update version * adding method required by the new device API design * Auto update version * using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in `quimb` * taking some further inputs from the new device API * Perhaps decided the overall structure of `LIghtningTensor` * Auto update version * adding docs to methods * temporary changes so that `pylint` does not complain at this stage * running `isort` * re-running formatter after `isort` * re-running formatter after `isort` * Applying suggested formatting change from CI * adding tmp unit tests * Adding `quimb` in `requirements.txt` * runing `isort` on mps test * removing `quimb` from requirement and deleting unit tests for `lightning.tensor` * Auto update version * re-inserting unit tests with an additional `yml` file * running isort on quimb test * changing name of yml file * preventing error in import * updating yml file * inserting `quimb` package in requirements-dev * strange error with `quimb` * strange error with `quimb` * specifying scipy version * removing installation of scipy from yml file * removing the new `yml` file * testing if tests are tested * Covering all lines in tests * forgot final line for formatter * Python formatter on CI complaints * covering missing lines * formatter on CI complaints * Trying not to skip test if Cpp is enabled * skipping tests if Cpp is enabled * removing the only line not covered by tests so far * Auto update version * Applying suggestions from code review and making the `state` attribute private (new API design) * Python formatter * removing params from `QuimbMPS` * Auto update version * removing `**kwargs` from `QuimbMPS` * removing unnecessary param at this stage * covering test line * formatter... * removing param description * Making `pylint` happy * forgot new arg in test * Updating base class and `preprocess` function * Updating `LightningTensor` class with new names from more advanced PR * Auto update version * Auto update version * Triggering CI * Auto update version * Trying to remove pin from `quimb` in `requirements.dev` * Auto update version * Auto update version * Removing infos on derivatives and using config options to pass parameters to interface * Usual `pylint` failures * Trying to solve formatting errors * typo in docstring * Sunday update: improved docstrings and structure * Removing method that was supposed to be in next PR * removing old TODO comment * Removing changes from the `setup.py` file * restoring previous format to `setup.py` * Auto update version from '0.36.0-dev34' to '0.36.0-dev41' * Auto update version from '0.36.0-dev40' to '0.36.0-dev41' * Removing kwargs as suggested from code review * Addressing comments from CR * Skipping tests if CPP binary is available * Auto update version from '0.36.0-dev42' to '0.36.0-dev43' * Auto update version from '0.36.0-dev43' to '0.36.0-dev44' * Restoring name in changelog (?) * Increasing time limit for Python tests * Applying suggestions from code review --------- Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum * Increase tolerance for a flaky test (test_single_return_value) (#703) * update dev version * increase tolerance * update changelog * trigger CIs * Auto update version from '0.36.0-dev44' to '0.36.0-dev45' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.36.0-dev45' to '0.36.0-dev46' * Remove LTensor stuff * Update changelog * Revert requirements-dev.txt * trigger ci * Update python_lightning_kokkos_test_durations * Restore 'all' tests in tests_lkcuda_python.yml * Fix durations paths. * Try --splitting-algorithm=least_duration * Try no -n auto lkcpu tests * One last test. --------- Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update changelog (#706) * Use wire order specified on instantiation (#705) * use map wires instead of map_to_standard_wires * oops * Update .github/CHANGELOG.md * black * Trigger CIs * add test * black on tests * Update .github/CHANGELOG.md --------- Co-authored-by: AmintorDusko Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update wire order support for probabilities (#707) * Begin expansion of probs tests * Update tests to exhaustively compute probs with wires * Update all tests in LQ Meas to use CHECK instead of REQUIRES for better signal of failures * Add Jet Permuter * Add noisy functionality * Fix permutation ordering * Update changelog * Fix wrong ordering in probs tests * Add recommendation from apache flink to purge azure dirs * Forbid out of order indices for probs with LK and LG in CPP layer * Remove MSFT tools from GH Actions * Just try to remove dotnet * List opt hostedtoolcache * Remove packages from /opt/hostedtoolcache * Fix missing test hit * Forbid and remove broken tests from LK probs ordering * Fix clang-tidy isms * Ensure libopenblas is not broken from failed apt pull with dev * Appease GH Action * Full remove GH action modifier step due to unexplained failures * Add bidreictional wire validation for LGPU CPP layer * Clang-tidy warning fix * Appease CT * Update JET license agreement * Sync version * pacify CodeFactor * make CodeFactor ignore all JET code * trigger ci * trigger ci * Split OMP builds using matrix. * trigger ci * Ignore .github but not self. * Fix cd.. * Fix path * Update changelog [skip ci] * Revert changes to reqs.txt * Auto update version from '0.37.0-dev0' to '0.37.0-dev2' * Auto update version from '0.37.0-dev1' to '0.37.0-dev2' * Update .github/CHANGELOG.md Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update .github/CHANGELOG.md Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> --------- Co-authored-by: AmintorDusko Co-authored-by: Dev version update bot Co-authored-by: ringo-but-quantum Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Pietropaolo Frisoni Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan * add changelog * Auto update version from '0.37.0-dev3' to '0.37.0-dev4' * fix multiple reset()/setbasisstate() & resolve comments * add blank lines to the end of each file * Auto update version from '0.37.0-dev8' to '0.37.0-dev9' * Auto update version from '0.37.0-dev9' to '0.37.0-dev10' --------- Co-authored-by: ringo-but-quantum Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: Pietropaolo Frisoni Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Raul Torres <138264735+rauletorresc@users.noreply.github.com> Co-authored-by: AmintorDusko * Fix LQ version checking out in LK-CPU tests (#723) * Fix checkout LQ * Auto update version from '0.37.0-dev6' to '0.37.0-dev7' * Try Ali's suggestion. * Auto update version from '0.37.0-dev7' to '0.37.0-dev8' * Auto update version from '0.37.0-dev8' to '0.37.0-dev9' * Update changelog. * Fix string comp. * Pin autoray<0.6.10 * Auto update version from '0.37.0-dev8' to '0.37.0-dev9' * trigger ci * trigger ci * Use float to define gates. * Revert. * Auto update version from '0.37.0-dev9' to '0.37.0-dev10' * Auto update version from '0.37.0-dev10' to '0.37.0-dev11' * Fix quimb dep. --------- Co-authored-by: ringo-but-quantum Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Kokkos gate functors are templated over the coefficient interaction function (#640) * Example of applyNC1Functor * Auto update version * WIP * Rewrite 1-gate functors. * Refactor 2-gate functors. * WIP * Finish gate functor refactor. * Prune gate functor modules. * Auto update version * Remove whitespace. * Fix globalphase. * shots=20000 => shots=40000 * run isort with python3.9 * WIP gen * Rewrite generators in terms of applyNCN. * Auto update version * trigger ci * Auto update version * trigger ci * Update changelog [skip ci]. * Kokkos views can be copied. * Auto update version * Auto update version * Remove empty line. * Auto update version * trigger ci * Auto update version * trigger ci * Update pennylane_lightning/core/src/simulators/lightning_kokkos/gates/BasicGateFunctors.hpp Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update pennylane_lightning/core/src/simulators/lightning_kokkos/gates/BasicGeneratorFunctors.hpp Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Update pennylane_lightning/core/src/simulators/lightning_kokkos/gates/MatrixGateFunctors.hpp Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> * Auto update version * Update pennylane_lightning/core/src/simulators/lightning_kokkos/gates/BasicGeneratorFunctors.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/simulators/lightning_kokkos/gates/MatrixGateFunctors.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Upgrade gates module and use it to test CRX, etc. * Update pennylane_lightning/core/src/simulators/lightning_kokkos/gates/BasicGateFunctors.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Cover 3-qubit case. * Auto update version * trigger ci * Add tests for applyXOperation. * Auto update version * trigger ci * Update SVK. * Auto update version * trigger ci * Auto update version * Auto update version * Remove obsolete generator functors module. * Revert pennylane_lightning/core/src/utils/config.h * Auto update version from '0.36.0-dev34' to '0.36.0-dev35' * Auto update version from '0.37.0-dev0' to '0.37.0-dev1' * Remove obsolete workflow. * Auto update version from '0.37.0-dev1' to '0.37.0-dev2' * Auto update version from '0.37.0-dev2' to '0.37.0-dev3' * Auto update version from '0.37.0-dev3' to '0.37.0-dev4' * Auto update version from '0.37.0-dev6' to '0.37.0-dev7' * Apply Shuli's suggestions. * Add Rot/CRot matrix tests. * Auto update version from '0.37.0-dev11' to '0.37.0-dev12' * Revert couple changes. * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Update pennylane_lightning/core/src/gates/Gates.hpp Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> * Revert --shots=40000 * Format & size_t => std::size_t. --------- Co-authored-by: Dev version update bot Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: ringo-but-quantum * Revert default.tensor to lightning.tensor. (#730) * Revert default.tensor to lightning.tensor. * Auto update version from '0.37.0-dev11' to '0.37.0-dev12' * Update changelog. * Auto update version from '0.37.0-dev12' to '0.37.0-dev13' --------- Co-authored-by: ringo-but-quantum * tidy up code * Auto update version from '0.37.0-dev13' to '0.37.0-dev14' * tidy up code * tidy up code * tidy up header files * update docstring * further tidy up code * quick fix * fix typo * Trigger multi-gpu CI * make format * Add todo for applyControlledTensorGate support * add required header file * set string->fucntor table as static * set gate name function map as singleton * Auto update version from '0.37.0-dev14' to '0.37.0-dev15' * Bump Kokkos version to 4.3.01 (#725) * Bump Kokkos version * Auto update version from '0.37.0-dev6' to '0.37.0-dev8' * Auto update version from '0.37.0-dev8' to '0.37.0-dev9' * Replace all Kokkos versions with 4.3 to update cache * Auto update version from '0.37.0-dev9' to '0.37.0-dev10' * Update changelog * Auto update version from '0.37.0-dev11' to '0.37.0-dev12' * Auto update version from '0.37.0-dev12' to '0.37.0-dev13' * Fix warning: moving a temporary object prevents copy elision * Ensure kokkos_swap used throughout * Auto update version from '0.37.0-dev13' to '0.37.0-dev14' --------- Co-authored-by: ringo-but-quantum * Auto update version from '0.37.0-dev14' to '0.37.0-dev15' * Fix PennyLane LightningKokkos and LightningQubits tests for stable/stable (#734) * comment pennylane master out * make Kokkos version configurable; checkout stable tag * re-trigger CIs * uncomment pennylane master * fix wrong condition * update version * fix for lqpu #732 * update lkcuda workflow and leave some notes to remember to change it back later * update stable branch to latest_release * checkout latest_release on LQubit tests [skip ci] * Trigger CIs * update changelog * Auto update version from '0.37.0-dev15' to '0.37.0-dev16' * update unit tests based on comments * Precision -> PrecisionT * fix version conflict * Auto update version from '0.37.0-dev15' to '0.37.0-dev16' * resolve some comments * Auto update version from '0.37.0-dev16' to '0.37.0-dev17' * resolve more comments * Auto update version from '0.37.0-dev16' to '0.37.0-dev17' * update base on PR#739 * Auto update version from '0.37.0-dev17' to '0.37.0-dev18' * add docstring for DynamicGateDataAccess * Auto update version from '0.37.0-dev18' to '0.37.0-dev19' * update docstring * Auto update version from '0.37.0-dev19' to '0.37.0-dev20' * Trigger CI --------- Co-authored-by: ringo-but-quantum Co-authored-by: Rashid N H M <95639609+rashidnhm@users.noreply.github.com> Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Amintor Dusko <87949283+AmintorDusko@users.noreply.github.com> Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com> Co-authored-by: Dev version update bot Co-authored-by: Pietropaolo Frisoni Co-authored-by: Christina Lee Co-authored-by: Lee James O'Riordan Co-authored-by: Vincent Michaud-Rioux Co-authored-by: Raul Torres <138264735+rauletorresc@users.noreply.github.com> Co-authored-by: AmintorDusko --- .github/CHANGELOG.md | 3 + pennylane_lightning/core/_version.py | 2 +- pennylane_lightning/core/src/CMakeLists.txt | 12 +- .../core/src/algorithms/CMakeLists.txt | 4 +- .../core/src/measurements/CMakeLists.txt | 4 +- .../core/src/observables/CMakeLists.txt | 4 +- .../core/src/simulators/base/CMakeLists.txt | 4 +- .../lightning_tensor/tensor/CMakeLists.txt | 2 +- .../tensor/base/TensorBase.hpp | 6 +- .../tensor/tncuda/TensorCuda.hpp | 13 +- .../lightning_tensor/tncuda/CMakeLists.txt | 4 +- .../lightning_tensor/tncuda/TNCudaBase.hpp | 156 ++- .../tncuda/base/TensornetBase.hpp | 10 +- .../tncuda/gates/CMakeLists.txt | 15 + .../tncuda/gates/TNCudaGateCache.hpp | 143 ++ .../tncuda/gates/tests/CMakeLists.txt | 37 + .../gates/tests/Test_MPSTNCuda_NonParam.cpp | 593 +++++++++ .../gates/tests/Test_MPSTNCuda_Param.cpp | 1177 +++++++++++++++++ .../tests/runner_lightning_tensor_gates.cpp | 2 + .../tncuda/tests/Tests_MPSTNCuda.cpp | 30 +- .../tncuda/utils/CMakeLists.txt | 2 +- .../lightning_tensor/utils/CMakeLists.txt | 2 +- .../utils/tncuda_utils/tncudaError.hpp | 2 +- .../cuda_utils}/cuGates_host.hpp | 274 +++- 24 files changed, 2423 insertions(+), 78 deletions(-) create mode 100644 pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/CMakeLists.txt create mode 100644 pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/TNCudaGateCache.hpp create mode 100644 pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/CMakeLists.txt create mode 100644 pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_NonParam.cpp create mode 100644 pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_Param.cpp create mode 100644 pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/runner_lightning_tensor_gates.cpp rename pennylane_lightning/core/src/{simulators/lightning_gpu/gates => utils/cuda_utils}/cuGates_host.hpp (84%) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 7f3a70fc96..eeed710e7b 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -2,6 +2,9 @@ ### New features since last release +* Add gate support to `cutensornet` backed `lightning.tensor` C++ layer. + [(#718)](https://github.com/PennyLaneAI/pennylane-lightning/pull/718) + * Add `cutensornet` backed `MPS` C++ layer to `lightning.tensor`. [(#704)](https://github.com/PennyLaneAI/pennylane-lightning/pull/704) diff --git a/pennylane_lightning/core/_version.py b/pennylane_lightning/core/_version.py index 402445d990..d9719dc847 100644 --- a/pennylane_lightning/core/_version.py +++ b/pennylane_lightning/core/_version.py @@ -16,4 +16,4 @@ Version number (major.minor.patch[-label]) """ -__version__ = "0.37.0-dev19" +__version__ = "0.37.0-dev20" diff --git a/pennylane_lightning/core/src/CMakeLists.txt b/pennylane_lightning/core/src/CMakeLists.txt index 4aae8a21ac..f25a6265dd 100644 --- a/pennylane_lightning/core/src/CMakeLists.txt +++ b/pennylane_lightning/core/src/CMakeLists.txt @@ -14,14 +14,10 @@ set(COMPONENT_SUBDIRS algorithms utils ) -if("${PL_BACKEND}" STREQUAL "lightning_tensor") - add_subdirectory(simulators) - add_subdirectory(utils) -else() - foreach(COMP ${COMPONENT_SUBDIRS}) - add_subdirectory(${COMP}) - endforeach() -endif() +foreach(COMP ${COMPONENT_SUBDIRS}) + add_subdirectory(${COMP}) +endforeach() + if (BUILD_TESTS) # Include macros supporting tests. diff --git a/pennylane_lightning/core/src/algorithms/CMakeLists.txt b/pennylane_lightning/core/src/algorithms/CMakeLists.txt index 7f856c4ea0..b174349f02 100644 --- a/pennylane_lightning/core/src/algorithms/CMakeLists.txt +++ b/pennylane_lightning/core/src/algorithms/CMakeLists.txt @@ -15,7 +15,7 @@ target_link_libraries(lightning_algorithms INTERFACE lightning_compile_option lightning_observables ) -if (BUILD_TESTS) +if (BUILD_TESTS AND NOT DEFINED PL_TENSOR) enable_testing() add_subdirectory("tests") -endif() \ No newline at end of file +endif() diff --git a/pennylane_lightning/core/src/measurements/CMakeLists.txt b/pennylane_lightning/core/src/measurements/CMakeLists.txt index f6670c5518..614c77b983 100644 --- a/pennylane_lightning/core/src/measurements/CMakeLists.txt +++ b/pennylane_lightning/core/src/measurements/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(lightning_measurements INTERFACE lightning_compile_option lightning_utils ) -if (BUILD_TESTS) +if (BUILD_TESTS AND NOT DEFINED PL_TENSOR) enable_testing() add_subdirectory("tests") -endif() \ No newline at end of file +endif() diff --git a/pennylane_lightning/core/src/observables/CMakeLists.txt b/pennylane_lightning/core/src/observables/CMakeLists.txt index e83adc8fe9..0e2e15e85c 100644 --- a/pennylane_lightning/core/src/observables/CMakeLists.txt +++ b/pennylane_lightning/core/src/observables/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(lightning_observables INTERFACE lightning_compile_option ) set_property(TARGET lightning_observables PROPERTY POSITION_INDEPENDENT_CODE ON) -if (BUILD_TESTS) +if (BUILD_TESTS AND NOT DEFINED PL_TENSOR) enable_testing() add_subdirectory("tests") -endif() \ No newline at end of file +endif() diff --git a/pennylane_lightning/core/src/simulators/base/CMakeLists.txt b/pennylane_lightning/core/src/simulators/base/CMakeLists.txt index 7c861657aa..04be451b69 100644 --- a/pennylane_lightning/core/src/simulators/base/CMakeLists.txt +++ b/pennylane_lightning/core/src/simulators/base/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(lightning_base INTERFACE lightning_compile_options set_property(TARGET lightning_base PROPERTY POSITION_INDEPENDENT_CODE ON) -if (BUILD_TESTS) +if (BUILD_TESTS AND NOT DEFINED PL_TENSOR) enable_testing() add_subdirectory("tests") -endif() \ No newline at end of file +endif() diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/CMakeLists.txt b/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/CMakeLists.txt index 59ed74f34e..dd1387cc9e 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/CMakeLists.txt +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/CMakeLists.txt @@ -11,7 +11,7 @@ if("${PL_TENSOR_BACKEND}" STREQUAL "cutensornet" AND NOT TNCUDA_UTILS_ADDED) add_subdirectory(tncuda) target_include_directories(${PL_BACKEND}_tensor INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/tncuda) target_link_libraries(${PL_BACKEND}_tensor INTERFACE tensor_cuda) - set(CUDA_UTILS_ADDED TRUE) + set(TNCUDA_UTILS_ADDED TRUE) endif() target_include_directories(${PL_BACKEND}_tensor INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/base) diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/base/TensorBase.hpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/base/TensorBase.hpp index 88d9cd153d..963b0a72b7 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/base/TensorBase.hpp +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/base/TensorBase.hpp @@ -19,6 +19,7 @@ #pragma once +#include #include #include "Error.hpp" @@ -28,7 +29,7 @@ namespace Pennylane::LightningTensor { /** * @brief CRTP-enabled base class for tensor. * - * @tparam Precision Floating point precision. + * @tparam PrecisionT Floating point precision. * @tparam Derived Derived class to instantiate using CRTP. */ template class TensorBase { @@ -44,7 +45,6 @@ template class TensorBase { : rank_(rank), modes_(modes), extents_(extents) { PL_ABORT_IF_NOT(rank_ == extents_.size(), "Please check if rank or extents are set correctly."); - length_ = 1; length_ = std::accumulate(extents.begin(), extents.end(), std::size_t{1}, std::multiplies<>()); } @@ -79,7 +79,7 @@ template class TensorBase { /** * @brief Return the number of elements of a tensor object. * - * @return std::vector Number of elements of a tensor object. + * @return std::size_t Number of elements of a tensor object. */ [[nodiscard]] std::size_t getLength() const { return length_; } }; diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/tncuda/TensorCuda.hpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/tncuda/TensorCuda.hpp index 8cae9e8501..8b8ec94515 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/tncuda/TensorCuda.hpp +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tensor/tncuda/TensorCuda.hpp @@ -27,17 +27,19 @@ #include "TensorBase.hpp" #include "cuda_helpers.hpp" +/// @cond DEV namespace { namespace cuUtil = Pennylane::LightningGPU::Util; using namespace Pennylane::LightningGPU; } // namespace +/// @endcond namespace Pennylane::LightningTensor::TNCuda { /** * @brief CRTP-enabled class for CUDA-capable Tensor. * - * @tparam Precision Floating point precision. + * @tparam PrecisionT Floating point precision. */ template @@ -61,14 +63,17 @@ class TensorCuda final : public TensorBase> { /** * @brief Explicitly copy data from GPU device to host memory. * - * @param sv Complex data pointer to receive data from device. + * @param host_tensor Complex data pointer to receive data from device. + * @param length Number of elements to copy. + * @param async If true, the copy is asynchronous. Only synchronous copy is + * supported now. */ - inline void CopyGpuDataToHost(std::complex *host_sv, + inline void CopyGpuDataToHost(std::complex *host_tensor, std::size_t length, bool async = false) const { PL_ABORT_IF_NOT(BaseType::getLength() == length, "Sizes do not match for Host and GPU data"); - data_buffer_->CopyGpuDataToHost(host_sv, length, async); + data_buffer_->CopyGpuDataToHost(host_tensor, length, async); } DataBuffer &getDataBuffer() { return *data_buffer_; } diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/CMakeLists.txt b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/CMakeLists.txt index 9339a82a2e..d7cb580f97 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/CMakeLists.txt +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/CMakeLists.txt @@ -37,9 +37,10 @@ option(PL_DISABLE_CUDA_SAFETY "Build without CUDA call safety checks" OFF) target_link_libraries(${PL_TENSOR} PUBLIC lightning_compile_options lightning_external_libs - ${PL_BACKEND}_utils + ${PL_BACKEND}_gates ${PL_BACKEND}_tensor ${PL_BACKEND}_tensornetBase + ${PL_BACKEND}_utils ) target_include_directories(${PL_TENSOR} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) @@ -57,6 +58,7 @@ endif() # Include all nested sources directories ############################################################################### set(COMPONENT_SUBDIRS base + gates utils ) foreach(COMP ${COMPONENT_SUBDIRS}) diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/TNCudaBase.hpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/TNCudaBase.hpp index eafcc4b08f..cff82d81ef 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/TNCudaBase.hpp +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/TNCudaBase.hpp @@ -20,12 +20,14 @@ #pragma once #include +#include #include #include #include #include +#include "TNCudaGateCache.hpp" #include "TensorBase.hpp" #include "TensorCuda.hpp" #include "TensornetBase.hpp" @@ -38,16 +40,24 @@ namespace { namespace cuUtil = Pennylane::LightningGPU::Util; using namespace Pennylane::LightningGPU; using namespace Pennylane::LightningTensor::TNCuda; +using namespace Pennylane::LightningTensor::TNCuda::Gates; using namespace Pennylane::LightningTensor::TNCuda::Util; } // namespace ///@endcond namespace Pennylane::LightningTensor::TNCuda { - -template -class TNCudaBase : public TensornetBase { +/** + * @brief CRTP-enabled base class for cuTensorNet backends. + * + * @tparam PrecisionT Floating point precision. + * @tparam Derived Derived class to instantiate using CRTP. + */ +template +class TNCudaBase : public TensornetBase { private: - using BaseType = TensornetBase; + using CFP_t = decltype(cuUtil::getCudaType(PrecisionT{})); + using ComplexT = std::complex; + using BaseType = TensornetBase; SharedTNCudaHandle handle_; cudaDataType_t typeData_; DevTag dev_tag_; @@ -57,16 +67,19 @@ class TNCudaBase : public TensornetBase { CUTENSORNET_STATE_PURITY_PURE; // Only supports pure tensor network // states as v24.03 + std::shared_ptr> gate_cache_; + public: TNCudaBase() = delete; explicit TNCudaBase(const std::size_t numQubits, int device_id = 0, cudaStream_t stream_id = 0) : BaseType(numQubits), handle_(make_shared_tncuda_handle()), - dev_tag_({device_id, stream_id}) { + dev_tag_({device_id, stream_id}), + gate_cache_(std::make_shared>(dev_tag_)) { // TODO this code block could be moved to base class and need to revisit // when working on copy ctor - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { typeData_ = CUDA_C_64F; typeCompute_ = CUTENSORNET_COMPUTE_64F; } else { @@ -87,10 +100,11 @@ class TNCudaBase : public TensornetBase { explicit TNCudaBase(const std::size_t numQubits, DevTag dev_tag) : BaseType(numQubits), handle_(make_shared_tncuda_handle()), - dev_tag_(dev_tag) { + dev_tag_(dev_tag), + gate_cache_(std::make_shared>(dev_tag_)) { // TODO this code block could be moved to base class and need to revisit // when working on copy ctor - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { typeData_ = CUDA_C_64F; typeCompute_ = CUTENSORNET_COMPUTE_64F; } else { @@ -141,6 +155,128 @@ class TNCudaBase : public TensornetBase { return dev_tag_; } + /** + * @brief Append multiple gates to the compute graph. + * NOTE: This function does not update the quantum state but only appends + * gate tensor operator to the graph. + * @param ops Vector of gate names to be applied in order. + * @param ops_wires Vector of wires on which to apply index-matched gate + * name. + * @param ops_adjoint Indicates whether gate at matched index is to be + * inverted. + * @param ops_params Vector of gate parameters. + */ + void + applyOperations(const std::vector &ops, + const std::vector> &ops_wires, + const std::vector &ops_adjoint, + const std::vector> &ops_params) { + const std::size_t numOperations = ops.size(); + PL_ABORT_IF_NOT( + numOperations == ops_wires.size(), + "Invalid arguments: number of operations, wires, and inverses " + "must all be equal"); + PL_ABORT_IF_NOT( + numOperations == ops_adjoint.size(), + "Invalid arguments: number of operations, wires and inverses" + "must all be equal"); + for (std::size_t i = 0; i < numOperations; i++) { + this->applyOperation(ops[i], ops_wires[i], ops_adjoint[i], + ops_params[i]); + } + } + + /** + * @brief Append multiple gate tensors to the compute graph. + * NOTE: This function does not update the quantum state but only appends + * gate tensor operator to the graph. + * @param ops Vector of gate names to be applied in order. + * @param ops_wires Vector of wires on which to apply index-matched gate + * name. + * @param ops_adjoint Indicates whether gate at matched index is to be + * inverted. + */ + void applyOperations(const std::vector &ops, + const std::vector> &ops_wires, + const std::vector &ops_adjoint) { + const std::size_t numOperations = ops.size(); + PL_ABORT_IF_NOT( + numOperations == ops_wires.size(), + "Invalid arguments: number of operations, wires, and inverses " + "must all be equal"); + PL_ABORT_IF_NOT( + numOperations == ops_adjoint.size(), + "Invalid arguments: number of operations, wires and inverses" + "must all be equal"); + for (std::size_t i = 0; i < numOperations; i++) { + this->applyOperation(ops[i], ops_wires[i], ops_adjoint[i], {}); + } + } + + /** + * @brief Append a single gate tensor to the compute graph. + * NOTE: This function does not update the quantum state but only appends + * gate tensor operator to the graph. + * @param opName Gate's name. + * @param wires Wires to apply gate to. + * @param adjoint Indicates whether to use adjoint of gate. + * @param params Optional parameter list for parametric gates. + * @param gate_matrix Optional gate matrix for custom gates. + */ + void applyOperation(const std::string &opName, + const std::vector &wires, + bool adjoint = false, + const std::vector ¶ms = {0.0}, + const std::vector &gate_matrix = {}) { + auto &&par = (params.empty()) ? std::vector{0.0} : params; + DataBuffer dummy_device_data( + Pennylane::Util::exp2(wires.size()), getDevTag()); + int64_t id; + std::vector stateModes(wires.size()); + std::transform( + wires.begin(), wires.end(), stateModes.begin(), [&](std::size_t x) { + return static_cast(BaseType::getNumQubits() - 1 - x); + }); + + // TODO: Need changes to support to the controlled gate tensor API once + // the API is finalized in cutensornet lib. + // Note `adjoint` in the cutensornet context indicates whether or not + // all tensor elements of the tensor operator will be complex + // conjugated. `adjoint` in the following API is not equivalent to + // `inverse` in the lightning context + PL_CUTENSORNET_IS_SUCCESS(cutensornetStateApplyTensorOperator( + /* const cutensornetHandle_t */ getTNCudaHandle(), + /* cutensornetState_t */ getQuantumState(), + /* int32_t numStateModes */ stateModes.size(), + /* const int32_t * stateModes */ stateModes.data(), + /* void * */ static_cast(dummy_device_data.getData()), + /* const int64_t *tensorModeStrides */ nullptr, + /* const int32_t immutable */ 1, + /* const int32_t adjoint */ adjoint, + /* const int32_t unitary */ 1, + /* int64_t * */ &id)); + if (!gate_matrix.empty()) { + std::vector matrix_cu(gate_matrix.size()); + std::transform(gate_matrix.begin(), gate_matrix.end(), + matrix_cu.begin(), [](const ComplexT &x) { + return cuUtil::complexToCu(x); + }); + auto gate_key = std::make_pair(opName, par); + gate_cache_->add_gate(static_cast(id), gate_key, + matrix_cu); + } else { + gate_cache_->add_gate(static_cast(id), opName, par); + } + PL_CUTENSORNET_IS_SUCCESS(cutensornetStateUpdateTensorOperator( + /* const cutensornetHandle_t */ getTNCudaHandle(), + /* cutensornetState_t */ getQuantumState(), + /* int64_t tensorId*/ id, + /* void* */ + static_cast( + gate_cache_->get_gate_device_ptr(static_cast(id))), + /* int32_t unitary*/ 1)); + } + protected: /** * @brief Returns the workspace size. @@ -174,7 +310,7 @@ class TNCudaBase : public TensornetBase { * @param worksize Memory size of a work space */ void setWorkSpaceMemory(cutensornetWorkspaceDescriptor_t &workDesc, - void *scratchPtr, std::size_t worksize) { + void *scratchPtr, std::size_t &worksize) { PL_CUTENSORNET_IS_SUCCESS(cutensornetWorkspaceSetMemory( /* const cutensornetHandle_t */ getTNCudaHandle(), /* cutensornetWorkspaceDescriptor_t */ workDesc, @@ -207,7 +343,7 @@ class TNCudaBase : public TensornetBase { std::size_t worksize = getWorkSpaceMemorySize(workDesc); - PL_ABORT_IF(std::size_t(worksize) > scratchSize, + PL_ABORT_IF(worksize > scratchSize, "Insufficient workspace size on Device!"); const std::size_t d_scratch_length = worksize / sizeof(std::size_t); diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/base/TensornetBase.hpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/base/TensornetBase.hpp index d6d05d27f7..c5ad342619 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/base/TensornetBase.hpp +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/base/TensornetBase.hpp @@ -24,7 +24,13 @@ #include "Error.hpp" namespace Pennylane::LightningTensor::TNCuda { -template class TensornetBase { +/** + * @brief CRTP-enabled base class for cutensornet. + * + * @tparam PrecisionT Floating point precision. + * @tparam Derived Derived class to instantiate using CRTP. + */ +template class TensornetBase { private: std::size_t numQubits_; std::vector qubitDims_; @@ -34,7 +40,7 @@ template class TensornetBase { explicit TensornetBase(const std::size_t numQubits) : numQubits_(numQubits) { - qubitDims_ = std::vector(numQubits, size_t{2}); + qubitDims_ = std::vector(numQubits, std::size_t{2}); } ~TensornetBase() = default; diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/CMakeLists.txt b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/CMakeLists.txt new file mode 100644 index 0000000000..236d31a9a9 --- /dev/null +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.20) +project(${PL_BACKEND}_gates LANGUAGES CXX CUDA) + +add_library(${PL_BACKEND}_gates INTERFACE) + +target_include_directories(${PL_BACKEND}_gates INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(${PL_BACKEND}_gates INTERFACE ${PL_BACKEND}_utils ${PL_BACKEND}_tensor lightning_gates) + +set_property(TARGET ${PL_BACKEND}_gates PROPERTY POSITION_INDEPENDENT_CODE ON) + +if(BUILD_TESTS) + enable_testing() + add_subdirectory("tests") +endif() diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/TNCudaGateCache.hpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/TNCudaGateCache.hpp new file mode 100644 index 0000000000..c024c65e74 --- /dev/null +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/TNCudaGateCache.hpp @@ -0,0 +1,143 @@ +// Copyright 2024 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. + +/** + * @file TNCudaGateCache.hpp + * Memory management for Gate tensor data affiliated to the tensor network + * graph. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "DataBuffer.hpp" +#include "DevTag.hpp" +#include "TensorCuda.hpp" +#include "cuGates_host.hpp" + +/// @cond DEV +namespace { +namespace cuUtil = Pennylane::LightningGPU::Util; +using namespace Pennylane::LightningGPU; +using namespace cuUtil; +using namespace Pennylane::LightningTensor::TNCuda; +} // namespace +/// @endcond + +namespace Pennylane::LightningTensor::TNCuda::Gates { + +/** + * @brief Memory management for gate tensor data on device and its id in the + * compute graph. + * + * @tparam PrecisionT Floating point precision. + */ +template class TNCudaGateCache { + public: + using CFP_t = decltype(cuUtil::getCudaType(PrecisionT{})); + using gate_key_info = std::pair>; + using gate_info = std::pair>; + TNCudaGateCache() = delete; + TNCudaGateCache(const TNCudaGateCache &other) = delete; + TNCudaGateCache(TNCudaGateCache &&other) = delete; + TNCudaGateCache(int device_id = 0, cudaStream_t stream_id = 0) + : device_tag_(device_id, stream_id), total_alloc_bytes_{0} {} + TNCudaGateCache(const DevTag device_tag) + : device_tag_{device_tag}, total_alloc_bytes_{0} {} + + ~TNCudaGateCache(){}; + + /** + * @brief Add gate numerical value to the cache, indexed by the id of gate + * tensor operator in the graph and its name and parameter value are + * recorded as well. + * + * @param gate_id The id of gate tensor operator in the computate graph. + * @param gate_name String representing the name of the given gate. + * @param gate_param Vector of parameter values. `{}` if non-parametric + * gate. + */ + void add_gate(const std::size_t gate_id, const std::string &gate_name, + [[maybe_unused]] std::vector gate_param = {}) { + auto gate_key = std::make_pair(gate_name, gate_param); + + auto &gateMap = + cuGates::DynamicGateDataAccess::getInstance(); + + add_gate(gate_id, gate_key, gateMap.getGateData(gate_name, gate_param)); + } + /** + * @brief Add gate numerical value to the cache, indexed by the id of gate + * tensor operator in the graph and its name and parameter value as well as + * the gate data on host. + * + * @param gate_id The id of gate tensor operator in the computate graph. + * @param gate_key String representing the name of the given gate as well as + * its associated parameter value. + * @param gate_data_host Vector of complex floating point values + * representing the gate data on host. + */ + + void add_gate(const std::size_t gate_id, gate_key_info gate_key, + const std::vector &gate_data_host) { + const std::size_t rank = Pennylane::Util::log2(gate_data_host.size()); + auto modes = std::vector(rank, 0); + auto extents = std::vector(rank, 2); + + auto &&tensor = + TensorCuda(rank, modes, extents, device_tag_); + + device_gates_.emplace( + std::piecewise_construct, std::forward_as_tuple(gate_id), + std::forward_as_tuple(gate_key, std::move(tensor))); + + device_gates_.at(gate_id).second.getDataBuffer().CopyHostDataToGpu( + gate_data_host.data(), gate_data_host.size()); + + total_alloc_bytes_ += (sizeof(CFP_t) * gate_data_host.size()); + } + + /** + * @brief Returns a pointer to the GPU device memory where the gate is + * stored. + * + * @param gate_id The id of gate tensor operator in the computate graph. + * @return const CFP_t* Pointer to gate values on device. + */ + CFP_t *get_gate_device_ptr(const std::size_t gate_id) { + return device_gates_.at(gate_id).second.getDataBuffer().getData(); + } + + private: + const DevTag device_tag_; + std::size_t total_alloc_bytes_; + + struct gate_info_hash { + std::size_t operator()(std::size_t key_id) const { + return std::hash()(key_id); + } + }; + + // device_gates_ is a map of id of gate tensor operator in the graph to the + // gate_info and gate_info is a pair of gate_info_key, which contains both + // gate name and parameter value, and the tensor data on device. + std::unordered_map device_gates_; +}; +} // namespace Pennylane::LightningTensor::TNCuda::Gates diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/CMakeLists.txt b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/CMakeLists.txt new file mode 100644 index 0000000000..4d86be0e8a --- /dev/null +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.20) + +project(${PL_BACKEND}_gates_tests) + +# Default build type for test code is Debug +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +include("${pennylane_lightning_SOURCE_DIR}/cmake/support_tests.cmake") +FetchAndIncludeCatch() + +################################################################################ +# Define library +################################################################################ + +add_library(${PL_BACKEND}_gates_tests INTERFACE) +target_link_libraries(${PL_BACKEND}_gates_tests INTERFACE Catch2::Catch2 + ${PL_BACKEND}_gates + ${PL_TENSOR} + ) + +ProcessTestOptions(${PL_BACKEND}_gates_tests) + +target_sources(${PL_BACKEND}_gates_tests INTERFACE runner_${PL_BACKEND}_gates.cpp) + +################################################################################ +# Define targets +################################################################################ +set(TEST_SOURCES Test_MPSTNCuda_NonParam.cpp + Test_MPSTNCuda_Param.cpp) + +add_executable(${PL_BACKEND}_gates_test_runner ${TEST_SOURCES}) +target_link_libraries(${PL_BACKEND}_gates_test_runner PRIVATE ${PL_BACKEND}_gates_tests) +catch_discover_tests(${PL_BACKEND}_gates_test_runner) + +install(TARGETS ${PL_BACKEND}_gates_test_runner DESTINATION bin) diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_NonParam.cpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_NonParam.cpp new file mode 100644 index 0000000000..bec9bb6674 --- /dev/null +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_NonParam.cpp @@ -0,0 +1,593 @@ +// Copyright 2024 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. + +#include +#include + +#include + +#include "DevTag.hpp" +#include "MPSTNCuda.hpp" +#include "TNCudaGateCache.hpp" + +#include "TestHelpers.hpp" + +/// @cond DEV +namespace { +using namespace Pennylane::LightningGPU; +using namespace Pennylane::LightningTensor; +using namespace Pennylane::LightningTensor::TNCuda::Gates; +using namespace Pennylane::Util; +namespace cuUtil = Pennylane::LightningGPU::Util; +} // namespace +/// @endcond + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::Identity", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("Hadamard", {index}, inverse); + + mps_state.applyOperation("Identity", {index}, inverse); + cp_t expected(1.0 / std::sqrt(2), 0); + + auto results = mps_state.getDataVector(); + + CHECK(expected.real() == + Approx(results[0b1 << ((num_qubits - 1 - index))].real())); + CHECK(expected.imag() == + Approx(results[0b1 << ((num_qubits - index - 1))].imag())); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::Hadamard", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("Hadamard", {index}, inverse); + cp_t expected(1.0 / std::sqrt(2), 0); + + auto results = mps_state.getDataVector(); + + CHECK(expected.real() == + Approx(results[0b1 << ((num_qubits - 1 - index))].real())); + CHECK(expected.imag() == + Approx(results[0b1 << ((num_qubits - index - 1))].imag())); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::PauliX", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("PauliX", {index}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results[0] == cuUtil::ZERO>()); + CHECK(results[0b1 << (num_qubits - index - 1)] == + cuUtil::ONE>()); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::PauliY", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const cp_t p = cuUtil::ConstMult( + std::complex(0.5, 0.0), + cuUtil::ConstMult(cuUtil::INVSQRT2>(), + cuUtil::IMAG>())); + const cp_t m = cuUtil::ConstMult(std::complex(-1, 0), p); + + const std::vector> expected_results = { + {m, m, m, m, p, p, p, p}, + {m, m, p, p, m, m, p, p}, + {m, p, m, p, m, p, m, p}}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("PauliY", {index}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::PauliZ", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const cp_t p(static_cast(0.5) * + cuUtil::INVSQRT2>()); + const cp_t m(cuUtil::ConstMult(cp_t{-1.0, 0.0}, p)); + + const std::vector> expected_results = { + {p, p, p, p, m, m, m, m}, + {p, p, m, m, p, p, m, m}, + {p, m, p, m, p, m, p, m}}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("PauliZ", {index}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::S", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + cp_t r(std::complex(0.5, 0.0) * + cuUtil::INVSQRT2>()); + cp_t i(cuUtil::ConstMult(r, cuUtil::IMAG>())); + + const std::vector> expected_results = { + {r, r, r, r, i, i, i, i}, + {r, r, i, i, r, r, i, i}, + {r, i, r, i, r, i, r, i}}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("S", {index}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::T", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + cp_t r(1.0 / (2.0 * std::sqrt(2)), 0); + cp_t i(1.0 / 4, 1.0 / 4); + + const std::vector> expected_results = { + {r, r, r, r, i, i, i, i}, + {r, r, i, i, r, r, i, i}, + {r, i, r, i, r, i, r, i}}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("T", {index}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CNOT", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply adjacent wire indices") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "CNOT", "CNOT"}, + {{0}, {0, 1}, {1, 2}}, + {false, inverse, inverse}); + + auto results = mps_state.getDataVector(); + + CHECK(results.front() == + cuUtil::INVSQRT2>()); + CHECK(results.back() == cuUtil::INVSQRT2>()); + } + + SECTION("Apply non-adjacent wire indices") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("Hadamard", {0}, false); + mps_state.applyOperation("CNOT", {0, 2}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results[0] == cuUtil::INVSQRT2>()); + CHECK(results[5] == cuUtil::INVSQRT2>()); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::SWAP", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply adjacent wire indices") { + std::vector expected{cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>()}; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("SWAP", {0, 1}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected)); + } + + SECTION("Apply non-adjacent wire indices") { + std::vector expected{cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>()}; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("SWAP", {0, 2}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected)); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CY", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + std::complex(0, -1 / sqrt(2)), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>()}; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("CY", {0, 1}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + + SECTION("Apply non-adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0.0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(0.0, 1.0 / sqrt(2))}; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("CY", {0, 2}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CZ", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(-1 / sqrt(2), 0), + cuUtil::ZERO>()}; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("CZ", {0, 1}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + + SECTION("Apply non-adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>()}; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("CZ", {0, 2}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::Toffoli", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0)}; + + std::size_t num_qubits = 3; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("Toffoli", {0, 1, 2}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + + SECTION("Apply non-adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>()}; + + std::size_t num_qubits = 4; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("Toffoli", {0, 2, 3}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CSWAP", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + SECTION("Apply adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>()}; + + std::size_t num_qubits = 3; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("CSWAP", {0, 1, 2}, inverse); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + } + + SECTION("Apply non-adjacent wire indices") { + std::vector expected_results{ + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + std::complex(1.0 / sqrt(2), 0), + cuUtil::ZERO>(), + cuUtil::ZERO>(), + cuUtil::ZERO>()}; + + std::size_t num_qubits = 4; + + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "PauliX"}, {{0}, {1}}, + {false, false}); + + mps_state.applyOperation("CSWAP", {0, 2, 3}, inverse); + + auto results = mps_state.getDataVector(); + // TODO remove the following line later. This is a test if we can + // call getDataVector() multiple times + auto results_test = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results)); + CHECK(results_test == Pennylane::Util::approx(expected_results)); + } + } +} diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_Param.cpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_Param.cpp new file mode 100644 index 0000000000..8b0077bca2 --- /dev/null +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/Test_MPSTNCuda_Param.cpp @@ -0,0 +1,1177 @@ +// Copyright 2024 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. + +#include +#include + +#include + +#include "DevTag.hpp" +#include "Gates.hpp" +#include "MPSTNCuda.hpp" +#include "TNCudaGateCache.hpp" +#include "TestHelpers.hpp" + +/// @cond DEV +namespace { +using namespace Pennylane::LightningGPU; +using namespace Pennylane::LightningTensor; +using namespace Pennylane::LightningTensor::TNCuda::Gates; +using namespace Pennylane::Util; +using namespace Pennylane; +namespace cuUtil = Pennylane::LightningGPU::Util; +} // namespace +/// @endcond + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::PhaseShift", "[MPSTNCuda_Param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles{0.3, 0.8, 2.4}; + const cp_t coef(1.0 / (2 * std::sqrt(2)), 0); + + std::vector> ps_data; + ps_data.reserve(angles.size()); + for (auto &a : angles) { + ps_data.push_back( + Pennylane::Gates::getPhaseShift(a)); + } + + std::vector> expected_results = { + {ps_data[0][0], ps_data[0][0], ps_data[0][0], ps_data[0][0], + ps_data[0][3], ps_data[0][3], ps_data[0][3], ps_data[0][3]}, + { + ps_data[1][0], + ps_data[1][0], + ps_data[1][3], + ps_data[1][3], + ps_data[1][0], + ps_data[1][0], + ps_data[1][3], + ps_data[1][3], + }, + {ps_data[2][0], ps_data[2][3], ps_data[2][0], ps_data[2][3], + ps_data[2][0], ps_data[2][3], ps_data[2][0], ps_data[2][3]}}; + + for (auto &vec : expected_results) { + scaleVector(vec, coef); + } + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("PhaseShift", {index}, inverse, + {angles[index]}); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::RX", "[MPSTNCuda_Param]", float, double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles{0.3, 0.8, 2.4}; + + // Results from default.qubit + std::vector results = {{0.34958337, -0.05283436}, + {0.32564424, -0.13768018}, + {0.12811281, -0.32952558}}; + + std::vector> expected_results{ + std::vector(std::size_t{1} << num_qubits, results[0]), + std::vector(std::size_t{1} << num_qubits, results[1]), + std::vector(std::size_t{1} << num_qubits, results[2]), + }; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("RX", {index}, inverse, {angles[index]}); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::RY", "[MPSTNCuda_Nonparam]", float, + double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles{0.3, 0.8, 2.4}; + + // Results from default.qubit + std::vector> expected_results{{{0.29674901, 0}, + {0.29674901, 0}, + {0.29674901, 0}, + {0.29674901, 0}, + {0.40241773, 0}, + {0.40241773, 0}, + {0.40241773, 0}, + {0.40241773, 0}}, + {{0.18796406, 0}, + {0.18796406, 0}, + {0.46332441, 0}, + {0.46332441, 0}, + {0.18796406, 0}, + {0.18796406, 0}, + {0.46332441, 0}, + {0.46332441, 0}}, + {{-0.20141277, 0}, + {0.45763839, 0}, + {-0.20141277, 0}, + {0.45763839, 0}, + {-0.20141277, 0}, + {0.45763839, 0}, + {-0.20141277, 0}, + {0.45763839, 0}}}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("RY", {index}, inverse, {angles[index]}); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::RZ", "[MPSTNCuda_Param]", float, double) { + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles{0.3, 0.8, 2.4}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + {{0.34958337, -0.05283436}, + {0.34958337, -0.05283436}, + {0.34958337, -0.05283436}, + {0.34958337, -0.05283436}, + {0.34958337, 0.05283436}, + {0.34958337, 0.05283436}, + {0.34958337, 0.05283436}, + {0.34958337, 0.05283436}}, + + {{0.32564424, -0.13768018}, + {0.32564424, -0.13768018}, + {0.32564424, 0.13768018}, + {0.32564424, 0.13768018}, + {0.32564424, -0.13768018}, + {0.32564424, -0.13768018}, + {0.32564424, 0.13768018}, + {0.32564424, 0.13768018}}, + + {{0.12811281, -0.32952558}, + {0.12811281, 0.32952558}, + {0.12811281, -0.32952558}, + {0.12811281, 0.32952558}, + {0.12811281, -0.32952558}, + {0.12811281, 0.32952558}, + {0.12811281, -0.32952558}, + {0.12811281, 0.32952558}}}; + + SECTION("Apply different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("RZ", {index}, inverse, {angles[index]}); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::ControlledPhaseShift", + "[MPSTNCuda_Param]", float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles{0.3, 2.4}; + const cp_t coef(1.0 / (2 * std::sqrt(2)), 0); + + std::vector> ps_data; + ps_data.reserve(angles.size()); + for (auto &a : angles) { + ps_data.push_back( + Pennylane::Gates::getPhaseShift(a)); + } + + std::vector> expected_results = { + {ps_data[0][0], ps_data[0][0], ps_data[0][0], ps_data[0][0], + ps_data[0][0], ps_data[0][0], ps_data[0][3], ps_data[0][3]}, + {ps_data[1][0], ps_data[1][0], ps_data[1][0], ps_data[1][0], + ps_data[1][0], ps_data[1][3], ps_data[1][0], ps_data[1][3]}}; + + for (auto &vec : expected_results) { + scaleVector(vec, coef); + } + + SECTION("Apply adjacent wire indices") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("ControlledPhaseShift", {0, 1}, inverse, + {angles[0]}); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wire indices") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("ControlledPhaseShift", {0, 2}, inverse, + {angles[1]}); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::Rot", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector> angles{ + std::vector{0.3, 0.8, 2.4}, + std::vector{0.5, 1.1, 3.0}, + std::vector{2.3, 0.1, 0.4}}; + + std::vector> expected_results{ + std::vector(0b1 << num_qubits), + std::vector(0b1 << num_qubits), + std::vector(0b1 << num_qubits)}; + + for (std::size_t i = 0; i < angles.size(); i++) { + const auto rot_mat = + Pennylane::Gates::getRot( + angles[i][0], angles[i][1], angles[i][2]); + expected_results[i][0] = rot_mat[0]; + expected_results[i][0b1 << (num_qubits - i - 1)] = rot_mat[2]; + } + + SECTION("Apply at different wire indices") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("Rot", {index}, inverse, angles[index]); + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results[index])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CRot", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = + std::vector{0.3, 0.8, 2.4}; + + std::vector expected_results = + std::vector(0b1 << num_qubits); + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("CRot", {0, 1}, inverse, angles); + + expected_results[0] = cp_t{1, 0}; + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results)); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("CRot", {0, 2}, inverse, angles); + + expected_results[0] = cp_t{1, 0}; + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results)); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::IsingXX", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles{0.3, 0.8}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits), + std::vector(1 << num_qubits), + std::vector(1 << num_qubits), + std::vector(1 << num_qubits)}; + expected_results[0][0] = {0.9887710779360422, 0.0}; + expected_results[0][6] = {0.0, -0.14943813247359922}; + + expected_results[1][0] = {0.9210609940028851, 0.0}; + expected_results[1][6] = {0.0, -0.3894183423086505}; + + expected_results[2][0] = {0.9887710779360422, 0.0}; + expected_results[2][5] = {0.0, -0.14943813247359922}; + + expected_results[3][0] = {0.9210609940028851, 0.0}; + expected_results[3][5] = {0.0, -0.3894183423086505}; + + SECTION("Apply adjacent wires") { + const std::size_t index = GENERATE(0, 1); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("IsingXX", {0, 1}, inverse, + {angles[index]}); + + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results[index])); + } + + SECTION("Apply non-adjacent wires") { + const std::size_t index = GENERATE(0, 1); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("IsingXX", {0, 2}, inverse, + {angles[index]}); + + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx( + expected_results[index + angles.size()])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::IsingXY", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.35355339, 0.0}), + std::vector(1 << num_qubits, {0.35355339, 0.0}), + }; + + expected_results[0][2] = {0.34958337, 0.05283436}; + expected_results[0][3] = {0.34958337, 0.05283436}; + expected_results[0][4] = {0.34958337, 0.05283436}; + expected_results[0][5] = {0.34958337, 0.05283436}; + + expected_results[1][1] = {0.34958337, 0.05283436}; + expected_results[1][3] = {0.34958337, 0.05283436}; + expected_results[1][4] = {0.34958337, 0.05283436}; + expected_results[1][6] = {0.34958337, 0.05283436}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("IsingXY", {0, 1}, inverse, angles); + + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + mps_state.applyOperation("IsingXY", {0, 2}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::IsingYY", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.34958337, 0.05283436}), + std::vector(1 << num_qubits, {0.34958337, 0.05283436}), + }; + + expected_results[0][2] = {0.34958337, -0.05283436}; + expected_results[0][3] = {0.34958337, -0.05283436}; + expected_results[0][4] = {0.34958337, -0.05283436}; + expected_results[0][5] = {0.34958337, -0.05283436}; + + expected_results[1][1] = {0.34958337, -0.05283436}; + expected_results[1][3] = {0.34958337, -0.05283436}; + expected_results[1][4] = {0.34958337, -0.05283436}; + expected_results[1][6] = {0.34958337, -0.05283436}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("IsingYY", {0, 1}, inverse, angles); + + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("IsingYY", {0, 2}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::IsingZZ", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.34958337, 0.05283436}), + std::vector(1 << num_qubits, {0.34958337, 0.05283436}), + }; + + expected_results[0][0] = {0.34958337, -0.05283436}; + expected_results[0][1] = {0.34958337, -0.05283436}; + expected_results[0][6] = {0.34958337, -0.05283436}; + expected_results[0][7] = {0.34958337, -0.05283436}; + + expected_results[1][0] = {0.34958337, -0.05283436}; + expected_results[1][2] = {0.34958337, -0.05283436}; + expected_results[1][5] = {0.34958337, -0.05283436}; + expected_results[1][7] = {0.34958337, -0.05283436}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("IsingZZ", {0, 1}, inverse, angles); + + CHECK(mps_state.getDataVector() == + Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("IsingZZ", {0, 2}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CRX", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.35355339, 0.0}), + std::vector(1 << num_qubits, {0.35355339, 0.0}), + }; + + expected_results[0][4] = {0.34958337, -0.05283436}; + expected_results[0][5] = {0.34958337, -0.05283436}; + expected_results[0][6] = {0.34958337, -0.05283436}; + expected_results[0][7] = {0.34958337, -0.05283436}; + + expected_results[1][4] = {0.34958337, -0.05283436}; + expected_results[1][5] = {0.34958337, -0.05283436}; + expected_results[1][6] = {0.34958337, -0.05283436}; + expected_results[1][7] = {0.34958337, -0.05283436}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("CRX", {0, 1}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("CRX", {0, 2}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CRY", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.35355339, 0.0}), + std::vector(1 << num_qubits, {0.35355339, 0.0}), + }; + + expected_results[0][4] = {0.29674901, 0.0}; + expected_results[0][5] = {0.29674901, 0.0}; + expected_results[0][6] = {0.40241773, 0.0}; + expected_results[0][7] = {0.40241773, 0.0}; + + expected_results[1][4] = {0.29674901, 0.0}; + expected_results[1][5] = {0.40241773, 0.0}; + expected_results[1][6] = {0.29674901, 0.0}; + expected_results[1][7] = {0.40241773, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("CRY", {0, 1}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("CRY", {0, 2}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::CRZ", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.35355339, 0.0}), + std::vector(1 << num_qubits, {0.35355339, 0.0}), + }; + + expected_results[0][4] = {0.34958337, -0.05283436}; + expected_results[0][5] = {0.34958337, -0.05283436}; + expected_results[0][6] = {0.34958337, 0.05283436}; + expected_results[0][7] = {0.34958337, 0.05283436}; + + expected_results[1][4] = {0.34958337, -0.05283436}; + expected_results[1][5] = {0.34958337, 0.05283436}; + expected_results[1][6] = {0.34958337, -0.05283436}; + expected_results[1][7] = {0.34958337, 0.05283436}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("CRZ", {0, 1}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + mps_state.applyOperation("CRZ", {0, 2}, inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::SingleExcitation", "[MPSTNCuda_param]", + float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.35355339, 0.0}), + std::vector(1 << num_qubits, {0.35355339, 0.0}), + }; + + expected_results[0][2] = {0.29674901, 0.0}; + expected_results[0][3] = {0.29674901, 0.0}; + expected_results[0][4] = {0.40241773, 0.0}; + expected_results[0][5] = {0.40241773, 0.0}; + + expected_results[1][1] = {0.29674901, 0.0}; + expected_results[1][3] = {0.29674901, 0.0}; + expected_results[1][4] = {0.40241773, 0.0}; + expected_results[1][6] = {0.40241773, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("SingleExcitation", {0, 1}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("SingleExcitation", {0, 2}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::SingleExcitationMinus", + "[MPSTNCuda_param]", float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.34958337, -0.05283436}), + std::vector(1 << num_qubits, {0.34958337, -0.05283436}), + }; + + expected_results[0][2] = {0.29674901, 0.0}; + expected_results[0][3] = {0.29674901, 0.0}; + expected_results[0][4] = {0.40241773, 0.0}; + expected_results[0][5] = {0.40241773, 0.0}; + + expected_results[1][1] = {0.29674901, 0.0}; + expected_results[1][3] = {0.29674901, 0.0}; + expected_results[1][4] = {0.40241773, 0.0}; + expected_results[1][6] = {0.40241773, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("SingleExcitationMinus", {0, 1}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("SingleExcitationMinus", {0, 2}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::SingleExcitationPlus", + "[MPSTNCuda_param]", float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.34958337, 0.05283436}), + std::vector(1 << num_qubits, {0.34958337, 0.05283436}), + }; + + expected_results[0][2] = {0.29674901, 0.0}; + expected_results[0][3] = {0.29674901, 0.0}; + expected_results[0][4] = {0.40241773, 0.0}; + expected_results[0][5] = {0.40241773, 0.0}; + + expected_results[1][1] = {0.29674901, 0.0}; + expected_results[1][3] = {0.29674901, 0.0}; + expected_results[1][4] = {0.40241773, 0.0}; + expected_results[1][6] = {0.40241773, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + + mps_state.applyOperation("SingleExcitationPlus", {0, 1}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations({"Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}}, {false, false, false}); + mps_state.applyOperation("SingleExcitationPlus", {0, 2}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::DoubleExcitation", "[MPSTNCuda_param]", + float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 5; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.1767767, 0.0}), + std::vector(1 << num_qubits, {0.1767767, 0.0}), + }; + + expected_results[0][6] = {0.1483745, 0.0}; + expected_results[0][7] = {0.1483745, 0.0}; + expected_results[0][24] = {0.20120886, 0.0}; + expected_results[0][25] = {0.20120886, 0.0}; + + expected_results[1][5] = {0.1483745, 0.0}; + expected_results[1][7] = {0.1483745, 0.0}; + expected_results[1][24] = {0.20120886, 0.0}; + expected_results[1][26] = {0.20120886, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations( + {"Hadamard", "Hadamard", "Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}, {3}, {4}}, {false, false, false, false, false}); + + mps_state.applyOperation("DoubleExcitation", {0, 1, 2, 3}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations( + {"Hadamard", "Hadamard", "Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}, {3}, {4}}, {false, false, false, false, false}); + + mps_state.applyOperation("DoubleExcitation", {0, 1, 2, 4}, inverse, + angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::DoubleExcitationMinus", + "[MPSTNCuda_param]", float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 5; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.17479168, -0.02641718}), + std::vector(1 << num_qubits, {0.17479168, -0.02641718}), + }; + + expected_results[0][6] = {0.1483745, 0.0}; + expected_results[0][7] = {0.1483745, 0.0}; + expected_results[0][24] = {0.20120886, 0.0}; + expected_results[0][25] = {0.20120886, 0.0}; + + expected_results[1][5] = {0.1483745, 0.0}; + expected_results[1][7] = {0.1483745, 0.0}; + expected_results[1][24] = {0.20120886, 0.0}; + expected_results[1][26] = {0.20120886, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations( + {"Hadamard", "Hadamard", "Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}, {3}, {4}}, {false, false, false, false, false}); + + mps_state.applyOperation("DoubleExcitationMinus", {0, 1, 2, 3}, + inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations( + {"Hadamard", "Hadamard", "Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}, {3}, {4}}, {false, false, false, false, false}); + + mps_state.applyOperation("DoubleExcitationMinus", {0, 1, 2, 4}, + inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::DoubleExcitationPlus", + "[MPSTNCuda_param]", float, double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 5; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + + // Results collected from `default.qubit` + std::vector> expected_results{ + std::vector(1 << num_qubits, {0.17479168, 0.02641718}), + std::vector(1 << num_qubits, {0.17479168, 0.02641718}), + }; + + expected_results[0][6] = {0.1483745, 0.0}; + expected_results[0][7] = {0.1483745, 0.0}; + expected_results[0][24] = {0.20120886, 0.0}; + expected_results[0][25] = {0.20120886, 0.0}; + + expected_results[1][5] = {0.1483745, 0.0}; + expected_results[1][7] = {0.1483745, 0.0}; + expected_results[1][24] = {0.20120886, 0.0}; + expected_results[1][26] = {0.20120886, 0.0}; + + SECTION("Apply adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + mps_state.reset(); + + mps_state.applyOperations( + {"Hadamard", "Hadamard", "Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}, {3}, {4}}, {false, false, false, false, false}); + + mps_state.applyOperation("DoubleExcitationPlus", {0, 1, 2, 3}, + inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[0])); + } + + SECTION("Apply non-adjacent wires") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperations( + {"Hadamard", "Hadamard", "Hadamard", "Hadamard", "Hadamard"}, + {{0}, {1}, {2}, {3}, {4}}, {false, false, false, false, false}, + {{0.0}, {0.0}, {0.0}, {0.0}, {0.0}}); + + mps_state.applyOperation("DoubleExcitationPlus", {0, 1, 2, 4}, + inverse, angles); + + auto results = mps_state.getDataVector(); + + CHECK(results == Pennylane::Util::approx(expected_results[1])); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::MultiRZ", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + std::size_t num_qubits = 5; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector angles = {0.3}; + SECTION("Throw errors") { + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + REQUIRE_THROWS_WITH(mps_state.applyOperation("MultiRZ", {0, 1}, + inverse, {angles[0]}), + Catch::Contains("Unsupported gate")); + } + } +} + +TEMPLATE_TEST_CASE("MPSTNCuda::Gates::Matrix", "[MPSTNCuda_param]", float, + double) { + // TODO only support inverse = false now + const bool inverse = GENERATE(false); + { + using cp_t = std::complex; + std::size_t num_qubits = 3; + std::size_t maxExtent = 2; + DevTag dev_tag{0, 0}; + + const std::vector x_gate{cuUtil::ZERO(), + cuUtil::ONE(), cuUtil::ONE(), + cuUtil::ZERO()}; + + SECTION("Append tensor operator with host data and wires") { + const std::size_t index = GENERATE(0, 1, 2); + MPSTNCuda mps_state{num_qubits, maxExtent, dev_tag}; + + mps_state.applyOperation("applyMatrix", {index}, inverse, {}, + x_gate); + + auto results = mps_state.getDataVector(); + + CHECK(results[0] == cuUtil::ZERO>()); + CHECK(results[0b1 << (num_qubits - index - 1)] == + cuUtil::ONE>()); + } + } +} diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/runner_lightning_tensor_gates.cpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/runner_lightning_tensor_gates.cpp new file mode 100644 index 0000000000..4ed06df1f7 --- /dev/null +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/gates/tests/runner_lightning_tensor_gates.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/tests/Tests_MPSTNCuda.cpp b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/tests/Tests_MPSTNCuda.cpp index 557ad1e0ea..2ba1dd04b5 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/tests/Tests_MPSTNCuda.cpp +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/tests/Tests_MPSTNCuda.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -33,9 +32,11 @@ using namespace Pennylane::LightningTensor; using namespace Pennylane::Util; using namespace Pennylane::LightningTensor::TNCuda; +/// @cond DEV namespace { namespace cuUtil = Pennylane::LightningGPU::Util; } // namespace +/// @endcond TEMPLATE_TEST_CASE("MPSTNCuda::Constructibility", "[Default Constructibility]", float, double) { @@ -50,22 +51,23 @@ TEMPLATE_PRODUCT_TEST_CASE("MPSTNCuda::Constructibility", using MPST = TestType; SECTION("MPST") { REQUIRE(!std::is_constructible_v); } - SECTION("MPST {const size_t, const size_t, DevTag }") { - REQUIRE(std::is_constructible_v>); + SECTION( + "MPST {const std::size_t, const std::size_t, DevTag }") { + REQUIRE(std::is_constructible_v>); } } TEMPLATE_TEST_CASE("MPSTNCuda::SetBasisStates() & reset()", "[MPSTNCuda]", float, double) { - std::vector> basisStates = { + std::vector> basisStates = { {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}}; SECTION("Failure for wrong basisState size") { std::size_t num_qubits = 3; std::size_t maxBondDim = 3; - std::vector basisState = {0, 0, 0, 0}; + std::vector basisState = {0, 0, 0, 0}; MPSTNCuda mps_state{num_qubits, maxBondDim}; @@ -78,7 +80,7 @@ TEMPLATE_TEST_CASE("MPSTNCuda::SetBasisStates() & reset()", "[MPSTNCuda]", SECTION("Failure for wrong basisState input") { std::size_t num_qubits = 3; std::size_t maxBondDim = 3; - std::vector basisState = {0, 0, 2}; + std::vector basisState = {0, 0, 2}; MPSTNCuda mps_state{num_qubits, maxBondDim}; @@ -98,7 +100,7 @@ TEMPLATE_TEST_CASE("MPSTNCuda::SetBasisStates() & reset()", "[MPSTNCuda]", mps_state.reset(); std::vector> expected_state( - size_t{1} << num_qubits, std::complex({0.0, 0.0})); + std::size_t{1} << num_qubits, std::complex({0.0, 0.0})); std::size_t index = 0; @@ -121,13 +123,13 @@ TEMPLATE_TEST_CASE("MPSTNCuda::SetBasisStates() & reset()", "[MPSTNCuda]", mps_state.setBasisState(basisStates[stateIdx]); std::vector> expected_state( - size_t{1} << num_qubits, std::complex({0.0, 0.0})); + std::size_t{1} << num_qubits, std::complex({0.0, 0.0})); std::size_t index = 0; - for (size_t i = 0; i < basisStates[stateIdx].size(); i++) { - index += - (size_t{1} << (num_qubits - i - 1)) * basisStates[stateIdx][i]; + for (std::size_t i = 0; i < basisStates[stateIdx].size(); i++) { + index += (std::size_t{1} << (num_qubits - i - 1)) * + basisStates[stateIdx][i]; } expected_state[index] = {1.0, 0.0}; @@ -149,7 +151,7 @@ TEMPLATE_TEST_CASE("MPSTNCuda::SetBasisStates() & reset()", "[MPSTNCuda]", mps_state.reset(); std::vector> expected_state( - size_t{1} << num_qubits, std::complex({0.0, 0.0})); + std::size_t{1} << num_qubits, std::complex({0.0, 0.0})); std::size_t index = 0; @@ -169,7 +171,7 @@ TEMPLATE_TEST_CASE("MPSTNCuda::getDataVector()", "[MPSTNCuda]", float, double) { SECTION("Get zero state") { std::vector> expected_state( - size_t{1} << num_qubits, std::complex({0.0, 0.0})); + std::size_t{1} << num_qubits, std::complex({0.0, 0.0})); expected_state[0] = {1.0, 0.0}; diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/utils/CMakeLists.txt b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/utils/CMakeLists.txt index a1610f6e7f..91b2f62596 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/utils/CMakeLists.txt +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/tncuda/utils/CMakeLists.txt @@ -10,7 +10,7 @@ foreach(BACKEND ${PL_BACKEND}) add_subdirectory(mps) target_include_directories(${PL_TENSOR}_utils INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/mps) target_link_libraries(${PL_TENSOR}_utils INTERFACE mps_tncuda_utils) - set(CUDA_UTILS_ADDED TRUE) + set(TNCUDA_UTILS_ADDED TRUE) endif() endforeach() diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/utils/CMakeLists.txt b/pennylane_lightning/core/src/simulators/lightning_tensor/utils/CMakeLists.txt index e68cc1ce6c..5ff72eb113 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/utils/CMakeLists.txt +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/utils/CMakeLists.txt @@ -11,7 +11,7 @@ foreach(BACKEND ${PL_BACKEND}) add_subdirectory(tncuda_utils) target_include_directories(${PL_BACKEND}_utils INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/tncuda_utils) target_link_libraries(${PL_BACKEND}_utils INTERFACE tncuda_utils) - set(CUDA_UTILS_ADDED TRUE) + set(TNCUDA_UTILS_ADDED TRUE) endif() endforeach() diff --git a/pennylane_lightning/core/src/simulators/lightning_tensor/utils/tncuda_utils/tncudaError.hpp b/pennylane_lightning/core/src/simulators/lightning_tensor/utils/tncuda_utils/tncudaError.hpp index f353ce2f0d..f5d1e9366c 100644 --- a/pennylane_lightning/core/src/simulators/lightning_tensor/utils/tncuda_utils/tncudaError.hpp +++ b/pennylane_lightning/core/src/simulators/lightning_tensor/utils/tncuda_utils/tncudaError.hpp @@ -27,7 +27,7 @@ /// @cond DEV namespace { using namespace Pennylane::Util; -} +} // namespace /// @endcond #ifndef CUDA_UNSAFE diff --git a/pennylane_lightning/core/src/simulators/lightning_gpu/gates/cuGates_host.hpp b/pennylane_lightning/core/src/utils/cuda_utils/cuGates_host.hpp similarity index 84% rename from pennylane_lightning/core/src/simulators/lightning_gpu/gates/cuGates_host.hpp rename to pennylane_lightning/core/src/utils/cuda_utils/cuGates_host.hpp index c05154aeaa..95b3b21fbb 100644 --- a/pennylane_lightning/core/src/simulators/lightning_gpu/gates/cuGates_host.hpp +++ b/pennylane_lightning/core/src/utils/cuda_utils/cuGates_host.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include "cuda_helpers.hpp" @@ -115,11 +116,10 @@ template static constexpr auto getS() -> std::vector { * of T gate data. */ template static constexpr auto getT() -> std::vector { - return { - cuUtil::ONE(), cuUtil::ZERO(), cuUtil::ZERO(), - cuUtil::ConstMultSC( - cuUtil::SQRT2().x)>() / 2, - cuUtil::ConstSum(cuUtil::ONE(), -cuUtil::IMAG()))}; + return {cuUtil::ONE(), cuUtil::ZERO(), cuUtil::ZERO(), + cuUtil::ConstMultSC( + cuUtil::SQRT2().x)>() / 2, + cuUtil::ConstSum(cuUtil::ONE(), cuUtil::IMAG()))}; } /** @@ -554,6 +554,7 @@ static auto getCRZ(U angle) -> std::vector { cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), + cuUtil::ZERO(), second}; } @@ -653,17 +654,25 @@ template static auto getSingleExcitation(U angle) -> std::vector { const U p2 = angle / 2; const CFP_t c{std::cos(p2), 0}; - const CFP_t s{std::sin(p2), 0}; + // TODO: To remove conditional compilation here in the future, current + // implementation will block the simultaneous installation of LGPU and + // cutensornet backends + +#ifdef _ENABLE_PLGPU + const CFP_t s{-std::sin(p2), 0}; // column-major +#else + const CFP_t s{std::sin(p2), 0}; // row-major +#endif return {cuUtil::ONE(), cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), c, - s, + -s, cuUtil::ZERO(), cuUtil::ZERO(), - -s, + s, c, cuUtil::ZERO(), cuUtil::ZERO(), @@ -730,17 +739,25 @@ static auto getSingleExcitationMinus(U angle) -> std::vector { const CFP_t e = cuUtil::complexToCu>(std::exp(std::complex(0, -p2))); const CFP_t c{std::cos(p2), 0}; - const CFP_t s{std::sin(p2), 0}; +// TODO: To remove conditional compilation here in the future, current +// implementation will block the simultaneous installation of LGPU and +// cutensornet backends +#ifdef _ENABLE_PLGPU + const CFP_t s{-std::sin(p2), 0}; // column-major +#else + const CFP_t s{std::sin(p2), 0}; // row-major +#endif + return {e, cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), c, - s, + -s, cuUtil::ZERO(), cuUtil::ZERO(), - -s, + s, c, cuUtil::ZERO(), cuUtil::ZERO(), @@ -809,17 +826,25 @@ static auto getSingleExcitationPlus(U angle) -> std::vector { const CFP_t e = cuUtil::complexToCu>(std::exp(std::complex(0, p2))); const CFP_t c{std::cos(p2), 0}; - const CFP_t s{std::sin(p2), 0}; + // TODO: To remove conditional compilation here in the future, current + // implementation will block the simultaneous installation of LGPU and + // cutensornet backends + +#ifdef _ENABLE_PLGPU + const CFP_t s{-std::sin(p2), 0}; // column-major +#else + const CFP_t s{std::sin(p2), 0}; // row-major +#endif return {e, cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), cuUtil::ZERO(), c, - s, + -s, cuUtil::ZERO(), cuUtil::ZERO(), - -s, + s, c, cuUtil::ZERO(), cuUtil::ZERO(), @@ -884,13 +909,21 @@ template static auto getDoubleExcitation(U angle) -> std::vector { const U p2 = angle / 2; const CFP_t c{std::cos(p2), 0}; - const CFP_t s{std::sin(p2), 0}; + // TODO: To remove conditional compilation here in the future, current + // implementation will block the simultaneous installation of LGPU and + // cutensornet backends + +#ifdef _ENABLE_PLGPU + const CFP_t s{-std::sin(p2), 0}; // column-major +#else + const CFP_t s{std::sin(p2), 0}; // row-major +#endif std::vector mat(256, cuUtil::ZERO()); mat[0] = cuUtil::ONE(); mat[17] = cuUtil::ONE(); mat[34] = cuUtil::ONE(); mat[51] = c; - mat[60] = s; + mat[60] = -s; mat[68] = cuUtil::ONE(); mat[85] = cuUtil::ONE(); mat[102] = cuUtil::ONE(); @@ -899,7 +932,7 @@ static auto getDoubleExcitation(U angle) -> std::vector { mat[153] = cuUtil::ONE(); mat[170] = cuUtil::ONE(); mat[187] = cuUtil::ONE(); - mat[195] = -s; + mat[195] = s; mat[204] = c; mat[221] = cuUtil::ONE(); mat[238] = cuUtil::ONE(); @@ -956,13 +989,21 @@ static auto getDoubleExcitationMinus(U angle) -> std::vector { const CFP_t e = cuUtil::complexToCu>(std::exp(std::complex(0, -p2))); const CFP_t c{std::cos(p2), 0}; - const CFP_t s{std::sin(p2), 0}; + // TODO: To remove conditional compilation here in the future, current + // implementation will block the simultaneous installation of LGPU and + // cutensornet backends + +#ifdef _ENABLE_PLGPU + const CFP_t s{-std::sin(p2), 0}; // column-major +#else + const CFP_t s{std::sin(p2), 0}; // row-major +#endif std::vector mat(256, cuUtil::ZERO()); mat[0] = e; mat[17] = e; mat[34] = e; mat[51] = c; - mat[60] = s; + mat[60] = -s; mat[68] = e; mat[85] = e; mat[102] = e; @@ -971,7 +1012,7 @@ static auto getDoubleExcitationMinus(U angle) -> std::vector { mat[153] = e; mat[170] = e; mat[187] = e; - mat[195] = -s; + mat[195] = s; mat[204] = c; mat[221] = e; mat[238] = e; @@ -1044,13 +1085,20 @@ static auto getDoubleExcitationPlus(U angle) -> std::vector { const CFP_t e = cuUtil::complexToCu>(std::exp(std::complex(0, p2))); const CFP_t c{std::cos(p2), 0}; - const CFP_t s{std::sin(p2), 0}; + // TODO: To remove conditional compilation here in the future, current + // implementation will block the simultaneous installation of LGPU and + // cutensornet backends +#ifdef _ENABLE_PLGPU + const CFP_t s{-std::sin(p2), 0}; // column-major +#else + const CFP_t s{std::sin(p2), 0}; // row-major +#endif std::vector mat(256, cuUtil::ZERO()); mat[0] = e; mat[17] = e; mat[34] = e; mat[51] = c; - mat[60] = s; + mat[60] = -s; mat[68] = e; mat[85] = e; mat[102] = e; @@ -1059,7 +1107,7 @@ static auto getDoubleExcitationPlus(U angle) -> std::vector { mat[153] = e; mat[170] = e; mat[187] = e; - mat[195] = -s; + mat[195] = s; mat[204] = c; mat[221] = e; mat[238] = e; @@ -1424,4 +1472,184 @@ static constexpr auto getP1111_CU() -> std::vector { cuUtil::ONE()}; } +/* + * @brief Dyanmical access the gate data based on the gate name and parameters. + * + * @tparam PrecisionT Required precision of gate (`float` or `double`). + */ +template class DynamicGateDataAccess { + private: + DynamicGateDataAccess() = default; + + public: + using CFP_t = decltype(cuUtil::getCudaType(PrecisionT{})); + DynamicGateDataAccess(DynamicGateDataAccess &&) = delete; + DynamicGateDataAccess(const DynamicGateDataAccess &) = delete; + DynamicGateDataAccess &operator=(const DynamicGateDataAccess &) = delete; + + ~DynamicGateDataAccess() = default; + + public: + static DynamicGateDataAccess &getInstance() { + static DynamicGateDataAccess instance; + return instance; + } + + auto + getGateData(const std::string &gate_name, + [[maybe_unused]] const std::vector ¶ms) const + -> std::vector { + if (nonparametric_gates_.find(gate_name) != + nonparametric_gates_.end()) { + return nonparametric_gates_.at(gate_name)(); + } else if (parametric_gates_.find(gate_name) != + parametric_gates_.end()) { + return parametric_gates_.at(gate_name)(params); + } else { + throw std::invalid_argument("Unsupported gate: " + gate_name + "."); + } + } + + private: + using ParamGateFunc = + std::function(const std::vector &)>; + using NonParamGateFunc = std::function()>; + using ParamGateFuncMap = std::unordered_map; + using NonParamGateFuncMap = + std::unordered_map; + + // TODO: Need changes to support to the controlled gate tensor API once the + // API is finalized in cutensornet lib. + NonParamGateFuncMap nonparametric_gates_{ + {"Identity", + []() -> std::vector { return cuGates::getIdentity(); }}, + {"PauliX", + []() -> std::vector { return cuGates::getPauliX(); }}, + {"PauliY", + []() -> std::vector { return cuGates::getPauliY(); }}, + {"PauliZ", + []() -> std::vector { return cuGates::getPauliZ(); }}, + {"S", []() -> std::vector { return cuGates::getS(); }}, + {"Hadamard", + []() -> std::vector { return cuGates::getHadamard(); }}, + {"T", []() -> std::vector { return cuGates::getT(); }}, + {"SWAP", + []() -> std::vector { return cuGates::getSWAP(); }}, + {"CNOT", + []() -> std::vector { return cuGates::getCNOT(); }}, + {"Toffoli", + []() -> std::vector { return cuGates::getToffoli(); }}, + {"CY", []() -> std::vector { return cuGates::getCY(); }}, + {"CZ", []() -> std::vector { return cuGates::getCZ(); }}, + {"CSWAP", + []() -> std::vector { return cuGates::getCSWAP(); }}}; + + // TODO: Need changes to support to the controlled gate tensor API once the + // API is finalized in cutensornet lib. + ParamGateFuncMap parametric_gates_{ + {"PhaseShift", + [](auto &¶ms) { + return cuGates::getPhaseShift( + std::forward(params[0])); + }}, + {"RX", + [](auto &¶ms) { + return cuGates::getRX( + std::forward(params[0])); + }}, + {"RY", + [](auto &¶ms) { + return cuGates::getRY( + std::forward(params[0])); + }}, + {"RZ", + [](auto &¶ms) { + return cuGates::getRZ( + std::forward(params[0])); + }}, + {"Rot", + [](auto &¶ms) { + return cuGates::getRot( + std::forward(params[0]), + std::forward(params[1]), + std::forward(params[2])); + }}, + {"CRX", + [](auto &¶ms) { + return cuGates::getCRX( + std::forward(params[0])); + }}, + {"CRY", + [](auto &¶ms) { + return cuGates::getCRY( + std::forward(params[0])); + }}, + {"CRZ", + [](auto &¶ms) { + return cuGates::getCRZ( + std::forward(params[0])); + }}, + {"CRot", + [](auto &¶ms) { + return cuGates::getCRot( + std::forward(params[0]), + std::forward(params[1]), + std::forward(params[2])); + }}, + {"ControlledPhaseShift", + [](auto &¶ms) { + return cuGates::getControlledPhaseShift( + std::forward(params[0])); + }}, + {"IsingXX", + [](auto &¶ms) { + return cuGates::getIsingXX( + std::forward(params[0])); + }}, + {"IsingYY", + [](auto &¶ms) { + return cuGates::getIsingYY( + std::forward(params[0])); + }}, + {"IsingZZ", + [](auto &¶ms) { + return cuGates::getIsingZZ( + std::forward(params[0])); + }}, + {"IsingXY", + [](auto &¶ms) { + return cuGates::getIsingXY( + std::forward(params[0])); + }}, + {"SingleExcitation", + [](auto &¶ms) { + return cuGates::getSingleExcitation( + std::forward(params[0])); + }}, + {"SingleExcitationMinus", + [](auto &¶ms) { + return cuGates::getSingleExcitationMinus( + std::forward(params[0])); + }}, + {"SingleExcitationPlus", + [](auto &¶ms) { + return cuGates::getSingleExcitationPlus( + std::forward(params[0])); + }}, + {"DoubleExcitation", + [](auto &¶ms) { + return cuGates::getDoubleExcitation( + std::forward(params[0])); + }}, + {"DoubleExcitationMinus", + [](auto &¶ms) { + return cuGates::getDoubleExcitationMinus( + std::forward(params[0])); + }}, + {"DoubleExcitationPlus", [](auto &¶ms) { + return cuGates::getDoubleExcitationPlus( + std::forward(params[0])); + }}}; +}; + } // namespace Pennylane::LightningGPU::cuGates