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


 FAQ / Troubleshooting