Intel QS
The Intel Quantum Simulator (Intel-QS) is a quantum circuit simulator designed to leverage multi-core and multi-node architectures efficiently. It employs a full representation of the qubit state while avoiding the explicit matrix representation of gates and other quantum operations. Intel-QS utilizes MPI (Message Passing Interface) protocols to manage communication between distributed resources used for storing and manipulating the quantum state.
1 Project Website
https://intel-qs.readthedocs.io/en/docs/index.html#
2 License
Apache-2.0 License
3 Version
v2.0.0-Beta
4 Hardware Plugins
Intel-QS do not support plugins to external quantum hardware.
5 Software Plugins
Intel-QS does not support software plugins; however, it provides a Python interface that facilitates the use of external packages.
6 HPC Components
Intel-QS supports the parallelisation of simulations through a hybrid implementation of MPI and OpenMP.
7 Installation & Deployment
7.1 Supported HPC Systems
SuperMUC-NG
Getting access to SuperMUC-NG: https://doku.lrz.de/access-and-login-to-supermuc-ng-11482471.html
7. 2 Installation
Intel-QS can be installed locally with only a C++ interface or with both C++ and Python interfaces.
7.2.1 C++ Interface Installation.
To install Intel-QS with only a C++ API, ensure that a reverse SSH tunneling is already set up. This will allow to clone sources from the repository.
For more information about reverse SSH tunneling, please refer to the documentation: https://doku.lrz.de/faq-installing-your-own-applications-on-supermug-ng-internet-access-from-supermuc-ng-10746066.html.
Alternatively you can clone the source in the LRZ Linux Cluster and compile in SuperMUC-NG, provided you have accounts on both systems.
Few modules need to be loaded before compilation:
1) intel-mpi/2019-intel
2) intel-oneapi-compilers/2021.4.0(default:intel)
3) cmake/3.21.4
4) intel-mkl/2020
Most of the above modules are loaded by default. If any module is missing, such as CMake, you should load it manually.
module load cmake
Then clone the Intel-QS from the repository. (https://github.com/intel/intel-qs)
git clone https://github.com/intel/intel-qs.git cd intel-qs
Once in the folder intel-qs, you can use the following commands to configure the build system and compile.
mkdir build cd build CXX=mpiicpc cmake -DIqsMPI=ON -DIqsUtest=OFF -DIqsPython=OFF -DIqsNoise=OFF -DBuildExamples=ON .. make
The above commands will generate a dynamic library called libiqs.so in the build/lib/ folder.
By linking that library with your C++ app, it's possible to use the Intel-QS with MPI.
Example for usage (find more in the repository https://github.com/intel/intel-qs)
#include "../include/qureg.hpp" using namespace std; #include <complex> #include <iomanip> // to use: setw() in making tables #include <iostream> // to use: std::cout, std::cin and std::endl // Definition of a utility macro to print only from the main rank. #define MPIout \ if (iqs::mpi::Environment::GetStateRank()==0) std::cout int main(int argc, char **argv) { unsigned myrank=0, nprocs=1; iqs::mpi::Environment env(argc, argv); if (env.IsUsefulRank()==false) return 0; myrank = iqs::mpi::Environment::GetStateRank(); nprocs = iqs::mpi::Environment::GetStateSize(); if (nprocs > 1) { if (myrank==0) fprintf(stderr, "example to be launched with a single process\n"); exit(1); } double expectation; MPIout << "------------------\n" << " Single qubit \n" << "------------------\n\n"; iqs::QubitRegister<ComplexDP> psi(1,"base",1); psi.EnableStatistics(); psi.ApplyHadamard(0); psi.Print(" initial state |psi>=|-> : "); expectation = psi.ExpectationValueX(0); MPIout << "<psi|X|psi> = " << expectation << "\n\n"; psi.Print(" current state should still be |psi>=|-> : "); // using the general method std::vector<unsigned> qubits(1,0); std::vector<unsigned> observables(1,1); expectation = psi.ExpectationValue(qubits,observables); MPIout << " general method __ <psi|X|psi> = " << expectation << "\n\n"; psi.Print(" current state should still be |psi>=|-> : "); psi.ApplyPauliZ(0); MPIout << "\n"; psi.Print(" current state should be Z|psi>=|+> : "); expectation = psi.ExpectationValueX(0); MPIout << " <psi|X|psi> = " << expectation << "\n"; expectation = psi.ExpectationValue(qubits,observables); MPIout << " general method __ <psi|X|psi> = " << expectation << "\n"; std::cout << std::endl; psi.GetStatistics(); MPIout << " goodbye \n" << std::endl; MPIout << "------------------\n" << " 4 qubits \n" << "------------------\n\n"; iqs::QubitRegister<ComplexDP> phi(4,"base",0); phi.ApplyPauliX(1); phi.ApplyHadamard(2); phi.ApplyPauliX(3); phi.ApplyHadamard(3); phi.Print(" initial state |phi> = |0> |1> |+> |-> = |01+-> :\n"); qubits.assign({0,2}); observables.assign({3,1}); expectation = phi.ExpectationValue(qubits,observables); MPIout << " <phi|Z_0 X_2|phi> = " << expectation << " <== should be 1\n"; qubits.assign({0,2}); observables.assign({3,2}); expectation = phi.ExpectationValue(qubits,observables); MPIout << " <phi|Z_0 Y_2|phi> = " << expectation << " <== should be 0\n"; return 0; }