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;
}