Welcome to Intel QS’s documentation!¶
Intel Quantum Simulator¶
Intel Quantum Simulator (Intel-QS), also known as qHiPSTER (The Quantum High Performance Software Testing Environment), is a simulator of quantum circuits optimized to take maximum advantage of multi-core and multi-nodes architectures. It is based on a complete representation of the qubit state, but avoids the explicit representation of gates and other quantum operations in terms of matrices. Intel-QS uses MPI (message-passing-interface) protocols to handle the communication between distributed resources that are used to store and manipulate the quantum state.
Build instructions¶
Intel-QS builds as a shared library which, once linked to the application program, allows to take advantage of the high-performance implementation of circuit simulations. The library can be built on a variety of different systems, from laptop to HPC server systems.
The directory structure of the repository can be found in intel-qs/docs/directory_structure.md.
The library object is: /builb/lib/libiqs.so
Requirements¶
The following packages are required by the installation:
CMake tools version 3.12+
MPICH3 library for enabling the distributed communication
optional: MKL for distributed random number generation
optional: PyBind11 (installed via conda, not pip) required by the Python bunding of Intel-QS
The first step is cloning the repository:
git clone https://github.com/iqusoft/intel-qs.git
cd intel-qs
Use Intel Parallel Studio compilers to build Intel-QS¶
If you wish to build Intel-QS using the latest Intel compiler technologies, then you need to configure your environment properly according to that tool’s documentation. Assuming that you have installed Intel Parallel Studio in the standard location on your system, you should invoke the following scripts through the source command on Linux.
source /opt/intel/bin/compilervars.sh -arch intel64 -platform linux
source /opt/intel/compiler_and_libraries/linux/mpi/intel64/bin/mpivars.sh
Now, use CMake to generate the appropriate makefiles to use the Intel Parallel Studio compilers.
The installation follows the out-of-source building and requires the creation of the directory build
.
This directory is used to collect all the files generated during the installation process.
mkdir build
cd build
CXX=mpiicpc cmake -DIqsMPI=ON -DIqsUtest=ON ..
make
By default, MKL is required when Intel compilers are used.
To re-build Intel-QS with different settings or options, we recommend to delete all content of the
build
directory and then restart from the CMake command.
Use standard GNU tools to build Intel-QS¶
If you wish to build Intel-QS using only standard GNU compilers type:
mkdir build
cd build
CXX=g++ cmake -DIqsMPI=OFF ..
make
By default, MKL is not required when GNU compilers are used.
Optionally, MPI can be included by setting the option -DIqsMPI=ON
instead. You must ensure
that you have at least version 3.1 of MPICH installed for the build to succeed.
https://www.mpich.org
Enable MPI protocol for distributed memory use¶
The above installation enables MPI functionalities to deploy Intel-QS on High Performance
Computing and Cloud Computing infrastructures. There is the option of disabling MPI:
simply set the CMake option selection to -DIqsMPI=OFF
(or just omit the option selection since MPI is disabled by default in the CMake build).
Enable Latest Vector Capability¶
To compile with the latest instruction set supported by your architecture, there is the option -DIqsNative
.
Compiled with -DIqsNative=ON
, the latest vector instructions available on your machine, e.g. AVX2, AVX512, are used.
By default, -DIqsNative=OFF
.
If the machine you compile and the machine you run have different vector capabilities, turning on IqsNative=ON
might cause run-time problems.
Underneath, this option uses -xhost
with Intel compilers and -march=native
with GNU compilers.
Enable Python binding (only available without MPI)¶
By default, whenever MPI is disabled, the building process includes the Python binding for Intel-QS. The binding code uses the Pybind11 library which needs to be installed via ‘conda’ (and not simply with pip) to include the relevant information in CMake. See this page for more info on this issue.
To disable the Python wrap, even without MPI, set the CMake option selection to
-DIqsPython=OFF
.
Unit test¶
By default, with MPI either enabled or disabled, the building process includes a suite
of unit tests written in the googletest framework.
Following the recommended integration, the CMake building process automatically downloads
the up-to-date repository of gtest and installs it in the build
path.
To disable the unit tests, set the CMake option selection to -DIqsUtest=OFF
.
To run the unit tests, from /build
launch the executable ./bin/utest
.
Recommended build for HPC.¶
The recommended building process requires Intel Math Kernel Library and the MPI-ICPC compiler.
When the program is run in hybrid configuration (OpenMP+MPI), we recommend to manage
the OpenMP affinity directly. Affinity settings can be set using the syntax:
KMP_AFFINITY=compact,1,0,granularity=fine
.
A quick look at the options can be found at
this page.
Docker: build image and run/execute container¶
Dockerfile
includes the instructions to build the docker image of an Ubuntu machine
with Intel-QS already installed. The image can be ‘run’ to create a container.
The container can be ‘executed’ to login into the machine.
docker build -t qhipster .
docker run -d -t qhipster
docker ps
docker exec -itd <container_id> /bin/bash
If Docker is used on a Windows host machine, the last line should be substituted by:
winpty docker exec -itd <container_id> //bin/bash
.
Getting started with Intel-QS¶
The simplest way of familiarize with the Intel Quantum Simulator is by exploring
the tutorials provided in the directory tutorials/
.
In particular, the code tutorials/get_started_with_IQS.cpp
provides step-by-step
description of the main commands to:
define a qubit register object, perform quantum gates, measure one or multiple qubits.
If the Python bindings were enabled, the same learning can be performed using the iPython
notebook tutorials/get_started_with_IQS.ipynb
.
How to contribute¶
Thanks for your interest in the project! We welcome pull requests from developers of all skill levels. If you would like to contribute to Intel-QS, please take a look to our contributing policy and also to the code of conduct. For any bug, we use GitHub issues GitHub issues. Please submit your request there.
How to contact us¶
If you have a question or want to discuss something, feel free to send an email to Justin Hogaboam, Gian Giacomo Guerreschi, or to Fabio Baruffa.
How to cite¶
When using Intel Quantum Simulator for research projects, please cite:
Gian Giacomo Guerreschi, Justin Hogaboam, Fabio Baruffa, Nicolas P. D. Sawaya Intel Quantum Simulator: A cloud-ready high-performance simulator of quantum circuits arXiv:2001.10554
The original implementation is described here:
Mikhail Smelyanskiy, Nicolas P. D. Sawaya, Alán Aspuru-Guzik qHiPSTER: The Quantum High Performance Software Testing Environment arXiv:1601.07195
Getting started with Intel Quantum Simulator: Examples¶
Tutorial on the basic use of Intel QS through its Python interface: Two examples are provided.
NOTE: Currently, the Python implementation only allows for single-core execution and does not take advantages of the MPI protocol. However the user can familiarize with the same functionalities available in the distributed implementation (only C++ at the moment) and the transition should be relatively straighforward since all methods maintain name and effect.
Import Intel QS library¶
Let’s start by importing the Python library with the class and methods defined in the C++ implementation.
[2]:
# Import the Python library with the C++ class and methods of Intel Quantum Simulator.
# If the library is not contained in the same folder of this notebook, its path has to be added.
import sys
sys.path.insert(0, '../lib_python')
import intelqs as simulator
# Import NumPy library with Intel specialization.
import numpy as np
from numpy import random_intel
# Import graphical library for plots.
import matplotlib.pyplot as plt
Example 1¶
Create the state of a quantum register, having \(N>3\) qubits.
The state is initialized as a computational basis state (using the keyword “base”) corresponding to the index 0.
The index corresponds to a \(N\)-bit integer in decimal representation. With \(N\) qubits there are \(2^N\) indices, from 0 to \(2^{N-1}\).
[3]:
# Allocate memory for the quantum register's state and initialize it to |000...0>.
num_qubits = 4;
if num_qubits<3:
num_qubits = 4;
psi1 = simulator.QubitRegister(num_qubits, "base", 0, 0);
Let us apply a X Pauli gate on qubit 0, effectively flipping it from |0> to |1>, followed by the Hadamard gate on all other qubits.
[4]:
# Let us apply a X Pauli gate on qubit 0, effectively flipping it from |0> to |1>.
psi1.ApplyPauliX(0);
# Let us apply an Hadamard gate on all other qubits.
for q in range(1,num_qubits):
psi1.ApplyHadamard(q);
In addition to one-qubit gates, universal quantum computation can be achieved via 2-qubit entangling gates. For example, we now apply a CNOT between qubit 2 (here the control qubit) and qubit 1 (target qubit).
[5]:
# Two qubit gates are applied in a similar way. For example, a C-NOT between qubit 2 (control qubit) and qubit 1 (target qubit):
control = 2;
target = 1;
psi1.ApplyCPauliX( control , target );
To extract information from the quantum register, one can obtain the probability of measuring a certain qubit in the computational basis and obtaining the outcome “1” (meaning that the state is in |1>). In this example we measure qubit 1. Once the probability is known, one can draw a random number to simulate the stochastic outcome of the measurement and collapse the wavefunction accordingly.
[7]:
# Compute the probability of qubit 1 being in state |1>.
measured_qubit = 1;
prob = psi1.GetProbability( measured_qubit );
print("Probability that qubit {}, if measured, is in state |1> = {}\n".format(measured_qubit, prob));
# Draw random number in [0,1)
r = np.random.rand()
if r < prob:
# Collapse the wavefunction according to qubit 1 being in |1>.
print("Simulated outcome is 1. Collapse the function accordingly.")
psi1.CollapseQubit(measured_qubit,True);
else:
# Collapse the wavefunction according to qubit 1 being in |0>
print("Simulated outcome is 0. Collapse the function accordingly.")
psi1.CollapseQubit(measured_qubit,False);
# In both cases one needs to re-normalize the wavefunction:
psi1.Normalize();
Probability that qubit 1, if measured, is in state |1> = 0.0
Simulated outcome is 0. Collapse the function accordingly.
Example 2¶
Create the state of a quantum register, having \(N>3\) qubits.
The state is initialized as a random state (using the keyword “rand”):
This requires a random number generator (RNG), that we initialize just before the second register. Notice that ‘777’ plays the role of the seed to initialize the RNG.
[8]:
num_qubits = 4;
if num_qubits<3:
num_qubits = 4;
psi2 = simulator.QubitRegister(num_qubits, "rand", 777, 0);
Let us apply one- and two-qubit gates as in the previous exmaple.
[9]:
# Let us apply a X Pauli gate on qubit 0, effectively flipping it from |0> to |1>.
psi2.ApplyPauliX(0);
# Let us apply an Hadamard gate on all other qubits.
for q in range(1,num_qubits):
psi2.ApplyHadamard(q);
One can define an arbitrary single-qubit gate and apply it to the chosen qubit.
In addition one can apply a custom one-qubit gate conditionally on the state of a control qubit.
[10]:
# Define an arbitrary single qubit gate and apply it to the chosen qubit.
# The quantum gate G is given by a 2x2 unitary matrix, here using a bi-dimensional NumPy array.
G = np.zeros((2,2),dtype=np.complex_);
G[0,0] = 0.592056606032915 + 0.459533060553574j;
G[0,1] = -0.314948020757856 - 0.582328159830658j;
G[1,0] = 0.658235557641767 + 0.070882241549507j;
G[1,1] = 0.649564427121402 + 0.373855203932477j;
qubit = 0;
psi2.Apply1QubitGate(qubit,G);
# It is also possible to apply the arbitrary gate specified by G controlled on the state of another qubit.
# G is applied conditioned on the control qubit being in |1>.
control = 1;
target = 2;
psi2.ApplyControlled1QubitGate( control, target, G);
# Notice that this output is directed to the terminal and not re-directed to the iPython notebook.
psi2.Print("After all gates.")
<<the output has been redirected to the terminal>>
To extract information from the quantum register, one can obtain the expectation value of Pauli strings.
For example, consider the Pauli string given by:
Such observable is defined by: - the position of the non-trivial Pauli matrices, in this case {0,2,3} - the corresponding Pauli matrices (X=1, Y=2, Z=3).
To facilitate the verification of the expectation value, we reinitialize the quantum state to |+-01>.
We also consider the Pauli staing
.
[12]:
# Prepare the state |+-01>
index = 2+8;
psi2.Initialize("base",index);
# Notice that GetProbability() does not change the state.
for qubit in range(0,num_qubits):
prob = psi2.GetProbability( qubit );
print("Probability that qubit {}, if measured, is in state |1> = {}\n".format(qubit, prob));
psi2.ApplyHadamard(0);
psi2.ApplyHadamard(1);
# The Pauli string given by: X_0 . id_1 . Z_2 . Y_3
# Such observable is defined by the position of the non-trivial Pauli matrices:
qubits_to_be_measured = [0,2,3]
# And by the corresponding Pauli matrices (X=1, Y=2, Z=3)
observables = [1,3,2]
# The expectation value <psi2|X_0.id_1.Z_2.Y_3|psi2> is obtained via:
average = psi2.ExpectationValue(qubits_to_be_measured, observables, 1.);
print("Expectation value <+-01|X_0.id_1.Z_2.Y_3|+-01> = {}\n".format(average));
# The expectation value <psi2|X_0.id_1.Z_2.Y_3|psi2> is obtained via:
qubits_to_be_measured = [0,2,3]
observables = [1,3,3]
average = psi2.ExpectationValue(qubits_to_be_measured, observables, 1.);
print("Expectation value <+-01|X_0.id_1.Z_2.Z_3|+-01> = {}\n".format(average));
# Trivial expectation:
average = psi2.ExpectationValue([0],[1], 1.);
print("Expectation value <+-01|X_0|+-01> = {}\n".format(average));
# The expectation value <psi2|X_0.id_1.id_2.Z_3|psi2> is obtained via:
average = psi2.ExpectationValue([0,3],[1,3], 1.);
print("Expectation value <+-01|X_0.Z_3|+-01> = {}\n".format(average));
Probability that qubit 0, if measured, is in state |1> = 0.0
Probability that qubit 1, if measured, is in state |1> = 1.0
Probability that qubit 2, if measured, is in state |1> = 0.0
Probability that qubit 3, if measured, is in state |1> = 1.0
Expectation value <+-01|X_0.id_1.Z_2.Y_3|+-01> = 0.0
Expectation value <+-01|X_0.id_1.Z_2.Z_3|+-01> = -0.9999999999999989
Expectation value <+-01|X_0|+-01> = 1.0
Expectation value <+-01|X_0.Z_3|+-01> = -1.0000000000000004
[13]:
# Prepare the state |+-01>
index = 2+8;
psi2.Initialize("base",index);
# Notice that GetProbability() does not change the state.
for qubit in range(0,num_qubits):
prob = psi2.GetProbability( qubit );
print("Probability that qubit {}, if measured, is in state |1> = {}\n".format(qubit, prob));
psi2.ApplyHadamard(0);
psi2.ApplyHadamard(1);
# The Pauli string given by: X_0 . id_1 . Z_2 . Y_3
# Such observable is defined by the position of the non-trivial Pauli matrices:
qubits_to_be_measured = [0,2,3]
# And by the corresponding Pauli matrices (X=1, Y=2, Z=3)
observables = [1,3,2]
# The expectation value <psi2|X_0.id_1.Z_2.Y_3|psi2> is obtained via:
average = psi2.ExpectationValue(qubits_to_be_measured, observables, 1.);
print("Expectation value <+-01|X_0.id_1.Z_2.Y_3|+-01> = {}\n".format(average));
# The expectation value <psi2|X_0.id_1.Z_2.Y_3|psi2> is obtained via:
qubits_to_be_measured = [0,2,3]
observables = [1,3,3]
average = psi2.ExpectationValue(qubits_to_be_measured, observables, 1.);
print("Expectation value <+-01|X_0.id_1.Z_2.Z_3|+-01> = {}\n".format(average));
Probability that qubit 0, if measured, is in state |1> = 0.0
Probability that qubit 1, if measured, is in state |1> = 1.0
Probability that qubit 2, if measured, is in state |1> = 0.0
Probability that qubit 3, if measured, is in state |1> = 1.0
Expectation value <+-01|X_0.id_1.Z_2.Y_3|+-01> = 0.0
Expectation value <+-01|X_0.id_1.Z_2.Z_3|+-01> = -0.9999999999999989
[14]:
# Extra expectation values.
# Prepare the state |+-01>
index = 2+8;
psi2.Initialize("base",index);
psi2.ApplyHadamard(0);
psi2.ApplyHadamard(1);
# The expectation value of X_0:
average = psi2.ExpectationValue([0],[1], 1.);
print("Expectation value <+-01|X_0|+-01> = {}\n".format(average));
# The expectation value of X_0.Z_3:
average = psi2.ExpectationValue([0,3],[1,3], 1.);
print("Expectation value <+-01|X_0.Z_3|+-01> = {}\n".format(average));
# The expectation value of X_0.Z_2:
average = psi2.ExpectationValue([0,2],[1,3], 1.);
print("Expectation value <+-01|X_0.Z_2|+-01> = {}\n".format(average));
# The expectation value of X_1.Z_2:
average = psi2.ExpectationValue([1,2],[1,3], 1.);
print("Expectation value <+-01|X_1.Z_2|+-01> = {}\n".format(average));
Expectation value <+-01|X_0|+-01> = 1.0
Expectation value <+-01|X_0.Z_3|+-01> = -1.0000000000000002
Expectation value <+-01|X_0.Z_2|+-01> = 0.999999999999998
Expectation value <+-01|X_1.Z_2|+-01> = -1.0000000000000002
### END |
[ ]:
Example using the extra features for QAOA circuits¶
The Quantum Approximate Optimization Algorithm (QAOA) is a variational algorithm to solve combinatorial problems. Here we provide the syntax to quickly define and simulate QAOA circuits.
As a concrete example, we consider the MaxCut problem on a linear graph of 6 vertices. It is trivially solved analytically, but the numerical procedure extends to more complicated instances.
NOTE: Currently, the Python implementation only allows for single-core execution and does not take advantages of the MPI protocol.
Import Intel QS library¶
We start by importing the Python library with the class and methods defined in the C++ implementation.
[1]:
# Import the Python library with the C++ class and methods of Intel Quantum Simulator.
# If the library is not contained in the same folder of this notebook, its path has to be added.
import sys
sys.path.insert(0, '../build/lib')
import intelqs_py as simulator
# Import NumPy library with Intel specialization.
import numpy as np
from numpy import random_intel
# Import graphical library for plots.
import matplotlib.pyplot as plt
Initialize the Max-Cut problem instance via its adjacency matrix¶
Specific instance: 0 – 1 – 2 – 3 – 4 – 5
We describe the instance by its adjacency matrix \(A\), represented as a bidimensional NumPy array.
Each of the \(2^6\) bipartitions of the 6 vertices is associated with a cut value (the number of edges connecting vertices of different color).
[2]:
# Number of vertices.
num_vertices = 6;
# Adjacency matrix.
A = np.zeros((num_vertices,num_vertices),dtype=np.int32);
# Since A is sparse, fill it element by element.
A[0,1] = 1;
A[1,0] = 1;
A[1,2] = 1;
A[2,1] = 1;
A[2,3] = 1;
A[3,2] = 1;
A[3,4] = 1;
A[4,3] = 1;
A[4,5] = 1;
A[5,4] = 1;
print("The adjacency matrix of the graph is:\n")
print(A)
#print(list(A.flatten()))
# Allocate memory for the diagonal of the objective function.
diag_cuts = simulator.QubitRegister(num_vertices, "base", 0, 0);
max_cut = simulator.InitializeVectorAsMaxCutCostFunction( diag_cuts, list(A.flatten()) );
print("\nThe max value of the cut is : {0:2d}".format(max_cut))
The adjacency matrix of the graph is:
[[0 1 0 0 0 0]
[1 0 1 0 0 0]
[0 1 0 1 0 0]
[0 0 1 0 1 0]
[0 0 0 1 0 1]
[0 0 0 0 1 0]]
The max value of the cut is : 5
### Implement a p=2 QAOA circuit¶
initialize the state in \(|000000\rangle\)
prepare the state in \(|++++++\rangle\)
iterate throught the QAOA steps (here p=2)
each step is composed by the global operation defined by the cost function C and the transverse field mixing
[3]:
# Number of qubits.
num_qubits = num_vertices;
# Allocate memory for the quantum register's state and initialize it to |000000>.
psi = simulator.QubitRegister(num_qubits, "base", 0, 0);
# Prepare state |++++++>
for qubit in range(num_qubits):
psi.ApplyHadamard(qubit);
# QAOA circuit:
qaoa_depth = 2;
# Random choice of QAOA parameters.
np.random.seed(7777);
gamma = np.random.random_sample((qaoa_depth,))*3.14159;
beta = np.random.random_sample((qaoa_depth,))*3.14159;
for p in range(qaoa_depth):
# exp(-i gamma C)
simulator.ImplementQaoaLayerBasedOnCostFunction(psi, diag_cuts, gamma[p]);
# exp(-i beta B)
for qubit in range(num_qubits):
psi.ApplyRotationX(qubit,beta[p]);
# At this point |psi> corresponds to the state at the end of the QAOA circuit.
Collect the results and visualize them in a histogram¶
[4]:
# The form of the histogram has been discussed privately.
histo = simulator.GetHistogramFromCostFunction(psi, diag_cuts, max_cut);
print("The probabilities of the cut values are:")
for c in range(max_cut+1):
print("cut={0:2d} : {1:1.4f}".format(c,histo[c]))
# Plot histogram.
x = np.arange(max_cut+1)
fig = plt.bar(x, histo, align='center', alpha=0.5)
#plt.xticks(x)
plt.xlabel('cut value')
plt.ylabel('probability of cut')
#plt.title('Summary of results')
plt.show()
The probabilities of the cut values are:
cut= 0 : 0.0397
cut= 1 : 0.1778
cut= 2 : 0.3483
cut= 3 : 0.2986
cut= 4 : 0.1120
cut= 5 : 0.0236

Simple test¶
This instance represents a disconnected graph with only two edges, namely: 0 – 1 2 3 4 – 5
We describe the instance by its adjacency matrix \(A\), represented as a bidimensional NumPy array.
Each of the \(2^6\) bipartitions of the 6 vertices is associated with a cut value (the number of edges connecting vertices of different color). For Half of the bipartitions the 0–1 edge can be cut and for half of the bipartitions, independently of the previous consideration, the 5–6 edge can be cut. The histogram has three bins (cut values = {0,1,2}) and ratio 1:2:1.
[5]:
# Number of vertices.
num_vertices = 6;
# Adjacency matrix.
A = np.zeros((num_vertices,num_vertices),dtype=np.int32);
# Since A is sparse, fill it element by element.
A[0,1] = 1;
A[1,0] = 1;
A[num_vertices-2,num_vertices-1] = 1;
A[num_vertices-1,num_vertices-2] = 1;
# Allocate memory for the diagonal of the objective function.
diag_cuts = simulator.QubitRegister(num_vertices, "base", 0, 0);
max_cut = simulator.InitializeVectorAsMaxCutCostFunction( diag_cuts, list(A.flatten()) );
# Number of qubits.
num_qubits = num_vertices;
# Allocate memory for the quantum register's state and initialize it to |000000>.
psi = simulator.QubitRegister(num_qubits, "base", 0, 0);
# Prepare state |++++++>
for qubit in range(num_qubits):
psi.ApplyHadamard(qubit);
# The form of the histogram has been discussed privately.
histo = simulator.GetHistogramFromCostFunction(psi, diag_cuts, max_cut);
print(histo)
# Plot histogram.
x = np.arange(max_cut+1)
fig = plt.bar(x, histo, align='center', alpha=0.5)
#plt.xticks(x)
plt.xlabel('cut value')
plt.ylabel('probability of cut')
#plt.title('Summary of results')
plt.show()
[0.2499999999999999, 0.4999999999999999, 0.2499999999999999]

## END |
Contributing¶
Thanks for your interest in the project!
Any contribution, project participation and pull request from developers are welcome. Please follow this process:
Clone this repository or fork it. Create a new branch and add your modifications.
Remember to add unit tests to verify the desired behavior of the new features or methods.
When the first version of the code is ready, create a pull-request to the development branch of
iqusoft/intel-qs
.Edits may be required to resolve conflicts since it is possible that the repository has changed while you worked on your new contribution. Please resolve the merge conflicts.
Verify that all unit tests, and not only the one added in the contribution, run correctly.
The IQS team will help with the revision of the pull-request.
To facilitate the review consider starting with small contributions (a couple files and ~100 lines).
For contributions that require substantial changes or changes in many files, please contact the IQS team to discuss the most effective strategy.
Creating your pull request from a fork? We suggest allowing edits from maintainers. Then, anyone with Write access to the upstream repository will be able to add commits to your branch. This can make the review process easier for maintainers since they can make a small change themselves instead of asking you to make the change.
If you would like to contribute to IQS, please visit our wiki page https://github.com/iqusoft/intel-qs/wiki/Contribute.
API References¶
Class Hierarchy¶
-
- Namespace qhipster
- Namespace qhipster::mpi
- Class Environment
- Class Exception
- Template Class AlignedAllocator
- Template Struct AlignedAllocator::rebind
- Template Class RandomNumberGenerator
- Template Class TinyMatrix
- Namespace qhipster::mpi
- Template Struct extract_value_type
- Template Struct extract_value_type< X< T > >
- Class GateCounter
- Class Header
- Template Class NoisyQureg
- Class Permutation
- Template Class QubitRegister
- Template Class QubitRegisterMetric
- Class Time
- Class Timer
- Namespace qhipster
File Hierarchy¶
-
- Directory include
- File alignedallocator.hpp
- File bitops.hpp
- File conversion.hpp
- File gate_counter.hpp
- File highperfkernels.hpp
- File mpi_env.hpp
- File mpi_exception.hpp
- File mpi_utils.hpp
- File NoisyQureg.hpp
- File permute.hpp
- File qaoa_features.hpp
- File QubitRegisterMetric.hpp
- File qureg.hpp
- File qureg_version.hpp
- File rng_utils.hpp
- File timer.hpp
- File tinymatrix.hpp
- File utils.hpp
- Directory include
Full API¶
Namespaces¶
Namespace qaoa¶
Contents
Functions¶
Template Function qaoa::GetExpectationValueSquaredFromCostFunction
Template Function qaoa::GetHistogramFromCostFunctionWithWeightsBinned
Template Function qaoa::GetHistogramFromCostFunctionWithWeightsRounded
Template Function qaoa::ImplementQaoaLayerBasedOnCostFunction
Template Function qaoa::InitializeVectorAsMaxCutCostFunction
Template Function qaoa::InitializeVectorAsWeightedMaxCutCostFunction
Namespace qhipster::detail¶
Contents
Namespace std¶
Classes and Structs¶
Template Struct AlignedAllocator::rebind¶
Defined in File alignedallocator.hpp
Nested Relationships¶
This struct is a nested type of Template Class AlignedAllocator.
Struct Documentation¶
-
template<typename
U
>
structqhipster::AlignedAllocator
::
rebind
¶
Class GateCounter¶
Defined in File gate_counter.hpp
Class Documentation¶
-
class
GateCounter
¶ The GateCounter class serves two main purposes: 1) To count the number of gates applied, divided by kind. 2) To estimate the circuit depth if scheduled in a greedy way.
Public Functions
-
GateCounter
(int new_num_qubits)¶
-
~GateCounter
()¶
-
void
Reset
()¶
-
int
GetTotalGateCount
()¶
-
int
GetOneQubitGateCount
()¶
-
int
GetTwoQubitGateCount
()¶
-
int
GetParallelDepth
()¶
-
void
OneQubitIncrement
(int qubit)¶ Update the counters and depth due to the action of a one-qubit gate.
-
void
TwoQubitIncrement
(int qubit_0, int qubit_1)¶ Update the counters and depth due to the action of a two-qubit gate.
-
void
Breakdown
()¶ Print the values of counters and depth.
-
Template Class NoisyQureg¶
Defined in File NoisyQureg.hpp
Inheritance Relationships¶
public QubitRegister< Type >
(Template Class QubitRegister)
Class Documentation¶
-
template<class
Type
= ComplexDP>
classNoisyQureg
: public QubitRegister<Type>¶ Class that expand
QubitRegister
states by adding noise between “logical” gates.- Parameters
num_qubit
: is the number of qubits When we refer to ``experimental’’ gates, it means that noise gates are excluded. For the simulation to be faithful (i.e. with one-to-one correspondence with the experimental gates), we include among the experimental gates both the gates for the algorithm and those to schedule it according to the connectivity of the specific hardware.
Public Functions
-
NoisyQureg
(unsigned num_qubits, unsigned RNG_seed = 12345, BaseType T1 = 2000, BaseType T2 = 1000)¶ Constructor.
-
~NoisyQureg
()¶ Default destructor.
-
void
Initialize
(std::string style, std::size_t base_index)¶
-
void
ResetTimeForAllQubits
()¶ Reset to zero the time elapsed for each and every qubit in the register.
-
void
ApplyNoiseGatesOnAllQubits
()¶ Apply the noise gates on each and every qubit. Then reset to time counter.
This is useful, for example, at the end of a circuit before measuring the quantities of interest: One has to apply the noise corresponding to the idle evolution between the last logical gate and the final time. The time from last logical gate is then resetted to zero for every qubit.
-
void
SetDecoherenceTime
(BaseType, BaseType)¶ Set the decoherence time in terms of T_1 and T_2 values (in accordance to the new noise model).
-
void
SetGateDurations
(BaseType, BaseType)¶ Update the duration of single- and two- qubit gates.
-
unsigned
GetTotalExperimentalGateCount
()¶ Return the current number of (experimental) 1- and 2-qubit gates.
-
unsigned
GetOneQubitExperimentalGateCount
()¶ Return the current number of (experimental) single-qubit gates.
-
unsigned
GetTwoQubitExperimentalGateCount
()¶ Return the current number of (experimental) two-qubit gates.
-
std::vector<unsigned>
GetExperimentalGateCount
(unsigned q1)¶ Return the number of (experimental) gates involving qubit q.
-
unsigned
GetExperimentalGateCount
(unsigned q1, unsigned q2)¶ Return the number of (experimental) gates involving qubits q1,q2.
-
void
AddNoiseOneQubitGate
(unsigned const)¶ Include and execute the noise gate corresponding to the idle time of a single qubit.
-
void
AddNoiseTwoQubitGate
(unsigned const, unsigned const)¶ Include and execute the noise gate corresponding to the idle time of two qubits.
-
void
NoiseGate
(unsigned const)¶ Noise gate corresponding to single-qubit rotation with appropriate (stochastic) angle.
Each noise gate is the product of three rotations around X,Y,Z axis (by a small angle each). We compute their product before applying it to the quantum register.
-
void
NoiseGate_OLD
(unsigned const)¶ Noise gate corresponding to single-qubit rotation with appropriate (stochastic) angle.
** OLD OLD OLD OLD OLD OLD **
Kept for historical reasons, it shouldy be deletead.
To obtain a single rotation around an arbitrary axis we use the relations: | a b c | | h-f | R = | d e f | > u = | c-g | > abs(u) = 2 sin( ‘angle’ ) | g h i | | d-b | > u/abs(u) = rotation axis
-
void
Apply1QubitGate
(unsigned const, qhipster::TinyMatrix<Type, 2, 2, 32>)¶
-
void
ApplyHadamard
(unsigned const)¶
-
void
ApplyRotationX
(unsigned const, BaseType)¶
-
void
ApplyRotationY
(unsigned const, BaseType)¶
-
void
ApplyRotationZ
(unsigned const, BaseType)¶
-
void
ApplyCPauliX
(unsigned const, unsigned const)¶
-
void
ApplyControlled1QubitGate
(unsigned const, unsigned const, qhipster::TinyMatrix<Type, 2, 2, 32>)¶
Class Permutation¶
Defined in File permute.hpp
Class Documentation¶
-
class
Permutation
¶ Public Functions
-
unsigned
operator[]
(std::size_t i)¶
-
unsigned
operator[]
(unsigned i)¶
-
int
operator[]
(int i)¶
-
std::size_t
size
()¶
-
std::string
GetMapStr
()¶
-
std::string
GetImapStr
()¶
-
Permutation
(std::size_t num_qubits)¶
-
Permutation
(std::vector<std::size_t> m)¶
-
std::size_t
Find
(std::size_t position)¶
-
void
SetNewPermutation
(std::vector<std::size_t> m)¶
-
std::string
dec2bin
(std::size_t in, std::size_t num_bits)¶
-
std::size_t
bin2dec
(std::string in)¶
-
std::size_t
lin2perm_
(std::size_t v)¶
-
std::size_t
perm2lin_
(std::size_t v)¶
-
std::string
lin2perm
(std::size_t v)¶
-
std::string
lin2perm
(std::string s)¶
-
std::string
perm2lin
(std::size_t v)¶
-
std::string
perm2lin
(std::string s)¶
-
void
prange
()¶
-
unsigned
Template Class AlignedAllocator¶
Defined in File alignedallocator.hpp
Class Documentation¶
-
template<typename
T
, unsigned intAlignment
>
classqhipster
::
AlignedAllocator
¶ An allocator returning aligned memory.
This class provides an aligned C++98 and C++11 conforming allocator.
- Pre
The alignment must be a power of 2.
Public Functions
-
AlignedAllocator
()¶
-
AlignedAllocator
(AlignedAllocator const&)¶
-
template<typename
U
>AlignedAllocator
(AlignedAllocator<U, Alignment> const&)¶
-
void
construct
(pointer p, const_reference t)¶
-
bool
operator==
(AlignedAllocator const&) const¶
-
bool
operator!=
(AlignedAllocator const&) const¶
-
template<typename
U
, unsigned intUAlignment
>
booloperator==
(AlignedAllocator<U, UAlignment> const&) const¶
-
template<typename
U
, unsigned intUAlignment
>
booloperator!=
(AlignedAllocator<U, UAlignment> const&) const¶
-
template<typename
U
>
structrebind
¶ Public Types
-
typedef AlignedAllocator<U, Alignment>
other
¶
-
typedef AlignedAllocator<U, Alignment>
Class Environment¶
Defined in File mpi_env.hpp
Class Documentation¶
-
class
qhipster::mpi
::
Environment
¶ A trimmed down version of the BOOST::MPI environment. Its purpose is to initialize the MPI library and partition the cluster or single threaded environment for parallel operations. In preparation of the Monte-Carlo simulations required for the noisy implementation, we provide a communicator over the ranks involved in a single MC simulation.
Specifically, we store two communicators:
pool_communicator: spanning all the useful ranks
state_communicator: spanning those ranks used in a single MC simulation (i.e. state)
Public Functions
-
Environment
(int &argc, char **&argv)¶ Intialize the MPI Environment.
It receives the same argc and argv arguments passed to the main function. If MPI is present, but has not been initialized, then MPI_Init will be called.
-
~Environment
()¶ Finalize the MPI Environment
If MPI is present and has been initizlized in the constructor then MPI_Finalize will be called here.
-
Environment
(Environment const&) = delete¶
-
Environment &
operator=
(Environment const&) = delete¶
Public Static Functions
-
void
UpdateStateComm
(int num_states, bool do_print_info = true)¶ Update the state and pool communicators.
- Pre
This can only be called when all ranks are still active.
-
bool
IsUsefulRank
()¶ Check whether the rank is useful or not.
-
int
GetPoolRank
()¶ The rank of the current MPI process: pool or state.
The PoolRank may not corresponds to that from MPI_COMM_WORLD due to dummy ranks. The rank is 0 if MPI is not present.
- Pre
If MPI is present, this can only be called after intializing MPI.
-
int
GetStateRank
()¶
-
int
GetRank
()¶
-
int
GetPoolSize
()¶ Number of MPI processes.
The PoolSize may not corresponds to that from MPI_COMM_WORLD due to dummy ranks. The number of processes is 1 if MPI is not present.
- Pre
If MPI is present, this can only be called after intializing MPI.
-
int
GetStateSize
()¶
-
int
GetSize
()¶
-
template<class
Type
>
TypeIncoherentSumOverAllStatesOfPool
(Type local_value)¶ Get incoherent average over all states of the pool.
- Parameters
local_value
: the address of the value stored in the local rank.
-
int
GetNumRanksPerNode
()¶
-
int
GetNumNodes
()¶
-
int
GetNodeId
()¶
-
int
GetStateId
()¶
-
int
GetNumStates
()¶
-
void
RemapStateRank
(int newme)¶
Class Exception¶
Defined in File mpi_exception.hpp
Class Documentation¶
-
class
qhipster::mpi
::
Exception
: public exception¶ Catch-all exception class for MPI errors.
Similar to the MPI exception class in the Boost libraries. Instances of this class will be thrown when an MPI error occurs.
Public Functions
-
Exception
(const char *routine, int error_code)¶ Build a new
Exception
exception.- Parameters
routine
: The MPI routine in which the error occurred. This should be a pointer to a string constant: it will not be copied.error_code
: The result code returned from the MPI routine that aborted with an error.
-
~Exception
()¶
-
const char *
what
() const¶ A description of the error that occurred.
-
const char *
routine
() const¶ Retrieve the name of the MPI routine that reported the error.
-
int
error_code
() const¶ Obtain the result code returned from the MPI routine that caused an error.
-
Template Class RandomNumberGenerator¶
Defined in File rng_utils.hpp
Class Documentation¶
-
template<typename
Type
>
classqhipster
::
RandomNumberGenerator
¶ Used to generate random numbers that are local to each rank, or common to the state or the complete pool.
The generation of numbers and the method to skip ahead are more efficient when MKL (and in particular VSL) is used.
Public Functions
-
RandomNumberGenerator
()¶
-
~RandomNumberGenerator
()¶
-
RandomNumberGenerator
(RandomNumberGenerator *source_rng)¶ Initialize RNG by copying the streams of the source RNG.
-
std::size_t
GetSeed
()¶ Get basic quantities.
-
std::size_t
GetNumGeneratedOrSkippedLocalNumbers
()¶
-
std::size_t
GetNumGeneratedOrSkippedStateNumbers
()¶
-
std::size_t
GetNumGeneratedOrSkippedPoolNumbers
()¶
-
void
SetSeedStreamPtrs
(std::size_t RNG_seed)¶ Set one different seed for each MPI rank (no MKL) or assign different streams (VSL).
-
void
SkipAhead
(std::size_t num_skip, std::string shared = "local")¶ Skip ahead.
-
void
UniformRandomNumbers
(Type *value, std::size_t size = 1UL, Type a = 0., Type b = 1., std::string shared = "local")¶ Generate random numbers in [a,b):
size indicates how many numbers
shared can be: local, state, pool
-
void
GaussianRandomNumbers
(Type *value, std::size_t size = 1UL, std::string shared = "local")¶ Generate random gaussian numbers (mean value = 0, std.dev = 1):
size indicates how many numbers
shared can be: local, state, pool
-
void
RandomIntegersInRange
(int *value, std::size_t size = 1UL, int a = 0, int b = 2, std::string shared = "local")¶ Generate random integers in [a,b), default being {0,1}..
size indicates how many numbers
shared can be: local, state, pool
-
Template Class TinyMatrix¶
Defined in File tinymatrix.hpp
Class Documentation¶
-
template<class
ValueType
, unsignedM
, unsignedN
= M, unsignedalign
= alignof(ValueType)>
classqhipster
::
TinyMatrix
¶ A small matrix with dimensions fixed at compile time.
The matrix is stored intenally as a two-dimensional C array, and thus in row-major ordering.
Public Types
-
using
size_type
= unsigned¶ an integral type large enought to store the size of the matrix
Public Functions
-
TinyMatrix
()¶ default-initizlize all matrix elements
-
template<class
U
>TinyMatrix
(std::initializer_list<std::initializer_list<U>> const &init)¶ initialize from an initializer list, i.e. a compile time given matrix
-
template<class
U
, unsignedalignrhs
>TinyMatrix
(TinyMatrix<U, M, N, alignrhs> const &rhs)¶ copy from a matrix with a potentially different type and alignment
-
TinyMatrix
(TinyMatrix const&) = default¶ the defaiult copy constructor
-
TinyMatrix &
operator=
(TinyMatrix const&) = default¶ the default assignment
-
template<class
U
, unsignedalignrhs
>
TinyMatrix &operator=
(TinyMatrix<U, M, N, alignrhs> const &rhs)¶ assign from a matrix with a potentially different type and alignment
-
template<class
U
>
TinyMatrix &operator=
(U const (&rhs)[M][N])¶ assign from a C-style array
-
constexpr size_type
size
() const¶ the size of the matrix, i.e. the number of matrix elements. This is the same as number of rows times number of columns
-
value_type
operator()
(unsigned i, unsigned j) const¶ access a matrix element of a const matrix
-
template<class
U
, unsignedalignrhs
>
booloperator==
(TinyMatrix<U, M, N, alignrhs> const &rhs) const¶ compare two matrices element-wise for equality
-
template<class
U
, unsignedalignrhs
>
booloperator!=
(TinyMatrix<U, M, N, alignrhs> const &rhs) const¶ compare two matrices element-wise for inequality
-
template<class
U
>
booloperator==
(U const (&rhs)[M][N])¶ compare two matrices element-wise for equality
-
template<class
U
>
booloperator!=
(U const (&rhs)[M][N])¶ compare two matrices element-wise for inequality
-
const_pointer
getPtr
() const¶ obtain a pointer to the first element of the matrix
-
RowType &
operator[]
(unsigned i)¶ C-style array subscript
the TinyMatrix can be indexed both using the mat(i,j) syntax or the C-style mat[i][j] syntax
-
RowType const &
operator[]
(unsigned i) const¶ C-style array subscript for a const matrix
the TinyMatrix can be indexed both using the mat(i,j) syntax or the C-style mat[i][j] syntax
-
template<unsigned
MSub
, unsignedNSub
= MSub>
TinyMatrix<ValueType, MSub, NSub, align>getSubMatrix
(unsigned i_start = 0, unsigned j_start = 0, unsigned i_stride = 1, unsigned j_stride = 1) const¶ Get submatrices
Returns the submatrix starting at i_start, j_start of size MSub, NSub using stride i_stride, j_stride
- Pre
Strides are strictly positive
- Pre
Parameters actually represent a submatrix (no index out of bounds)
- Parameters
i_start
: The starting row index \þaram j_start The starting column indexi_stride
: The row stride to use for accessing elementsj_stride
: The column stride to use for accessing elements
- Template Parameters
MSub
: The number of rows of the submatrixNSub
: The number of columns of the submatrix
-
void
print
(std::string name)¶
-
std::string
tostr
() const¶
Public Members
-
std::string
name
¶
-
using
Template Class QubitRegister¶
Defined in File qureg.hpp
Inheritance Relationships¶
public NoisyQureg< Type >
(Template Class NoisyQureg)public QubitRegisterMetric< Type >
(Template Class QubitRegisterMetric)
Class Documentation¶
-
template<class
Type
= ComplexDP>
classQubitRegister
¶ Subclassed by NoisyQureg< Type >, QubitRegisterMetric< Type >
Public Functions
-
QubitRegister
()¶
-
QubitRegister
(std::size_t num_qubits, std::string style = "", std::size_t base_index = 0, std::size_t tmp_spacesize_ = 0)¶
-
QubitRegister
(const QubitRegister &in)¶
-
~QubitRegister
()¶
-
void
AllocateAdditionalQubit
()¶
-
void
Allocate
(std::size_t new_num_qubits, std::size_t tmp_spacesize_)¶
-
void
Initialize
(std::size_t new_num_qubits, std::size_t tmp_spacesize_)¶
-
void
Initialize
(std::string style, std::size_t base_index)¶
-
std::size_t
LocalSize
() const¶
-
std::size_t
GlobalSize
() const¶
-
void
Resize
(std::size_t new_num_amplitudes)¶
-
std::size_t
size
() const¶
-
std::size_t
NumQubits
() const¶
-
size_t
TmpSize
() const¶
-
bool
check_bit
(std::size_t variable, std::size_t position) const¶
-
std::size_t
set_bit
(std::size_t variable, std::size_t position) const¶
-
std::size_t
clear_bit
(std::size_t variable, std::size_t position) const¶
-
void
EnableStatistics
()¶
-
void
GetStatistics
()¶
-
void
DisableStatistics
()¶
-
void
ResetStatistics
()¶
-
void
Permute
(std::vector<std::size_t> permutation_new_vec)¶
-
bool
Apply1QubitGate_helper
(unsigned qubit, TM2x2<Type> const &m, std::size_t sstate_ind, std::size_t estate_ind)¶
-
bool
ApplyControlled1QubitGate_helper
(unsigned control_qubit, unsigned target_qubit, TM2x2<Type> const &m, std::size_t sind, std::size_t eind)¶
-
void
ApplyControlled1QubitGate
(unsigned control_qubit, unsigned target_qubit, TM2x2<Type> const &m)¶
-
void
ApplySwap
(unsigned qubit1, unsigned qubit2)¶
-
void
ApplyISwap
(unsigned qubit1, unsigned qubit2)¶
-
void
Apply4thRootISwap
(unsigned qubit1, unsigned qubit2)¶
-
void
ApplySqrtISwap
(unsigned qubit1, unsigned qubit2)¶
-
void
Swap
(unsigned b1, unsigned b2)¶
-
void
ApplyPauliX
(unsigned const qubit)¶
-
void
ApplyPauliY
(unsigned const qubit)¶
-
void
ApplyPauliZ
(unsigned const qubit)¶
-
void
ApplyPauliSqrtX
(unsigned const qubit)¶
-
void
ApplyPauliSqrtY
(unsigned const qubit)¶
-
void
ApplyPauliSqrtZ
(unsigned const qubit)¶
-
void
ApplyT
(unsigned const qubit)¶
-
void
ApplyToffoli
(unsigned const qubit1, unsigned const qubit2, unsigned const qubit3)¶
-
void
ApplyHadamard
(unsigned const qubit)¶
-
void
ApplyCPauliX
(unsigned const control_qubit, unsigned const target_qubit)¶
-
void
ApplyCPauliY
(unsigned const control_qubit, unsigned const target_qubit)¶
-
void
ApplyCPauliZ
(unsigned const control_qubit, unsigned const target_qubit)¶
-
void
ApplyCPauliSqrtZ
(unsigned const control_qubit, unsigned const target_qubit)¶
-
void
ApplyCHadamard
(unsigned const control_qubit, unsigned const target_qubit)¶
-
void
TurnOnFusion
(unsigned log2llc = 20)¶
-
void
TurnOffFusion
()¶
-
bool
IsFusionEnabled
()¶
-
void
ApplyFusedGates
()¶
-
void
TurnOnSpecialize
()¶
-
void
TurnOffSpecialize
()¶
-
void
CollapseQubit
(unsigned qubit, bool value)¶
-
BaseType
ExpectationValue
(std::vector<unsigned> &qubits, std::vector<unsigned> &observables, BaseType coeff = 1.)¶
-
bool
operator==
(const QubitRegister &rhs)¶
-
BaseType
MaxAbsDiff
(QubitRegister &x, Type sfactor = Type(1.0, 0.))¶
-
BaseType
MaxL2NormDiff
(QubitRegister &x)¶
-
void
dumpbin
(std::string fn)¶
-
double
Entropy
()¶
-
std::vector<double>
GoogleStats
()¶
-
void
Normalize
()¶
-
Type
ComputeOverlap
(QubitRegister<Type> &psi)¶
-
void
Print
(std::string x, std::vector<std::size_t> qbits = {})¶
-
qhipster::RandomNumberGenerator<BaseType> *
GetRngPtr
()¶
-
void
ResetRngPtr
()¶
-
void
SetRngPtr
(qhipster::RandomNumberGenerator<BaseType> *rng_ptr)¶
-
void
SetSeedRngPtr
(std::size_t seed)¶
Public Members
-
std::size_t
num_qubits
¶
-
std::vector<Type, qhipster::AlignedAllocator<Type, 256>>
state_storage
¶
-
Permutation *
permutation
¶
-
GateCounter *
gate_counter
¶
-
std::size_t
llc_watermarkbit
¶
-
bool
imported_state
¶
-
bool
specialize
¶
-
bool
fusion
¶
-
unsigned
log2llc
¶
Public Static Functions
-
void
SetDoPrintExtraInfo
(bool value)¶
-
Template Class QubitRegisterMetric¶
Defined in File QubitRegisterMetric.hpp
Inheritance Relationships¶
public QubitRegister< Type >
(Template Class QubitRegister)
Class Documentation¶
-
template<class
Type
= ComplexDP>
classQubitRegisterMetric
: public QubitRegister<Type>¶ Public Functions
-
QubitRegisterMetric
(int iNQubits)¶
-
int
GetTotalQubitGateCount
()¶
-
int
GetOneQubitGateCount
()¶
-
int
GetTwoQubitGateCount
()¶
-
int
GetParallelDepth
()¶
-
void
ApplyHadamard
(int)¶
-
void
ApplyRotationX
(int, double)¶
-
void
ApplyRotationY
(int, double)¶
-
void
ApplyRotationZ
(int, double)¶
-
void
ApplyCPauliX
(int, int)¶
-
void
ApplyControlled1QubitGate
(int, int, qhipster::TinyMatrix<Type, 2, 2, 32>)¶
-
Class Time¶
Defined in File timer.hpp
Class Timer¶
Defined in File timer.hpp
Class Documentation¶
-
class
Timer
¶ The Timer class serves two purposes: 1) To provide a reliable and static call to Wtime() (since MPI_Wtime may not be available). 2) To provide a tidy way of profiling the code.
Public Functions
-
Timer
(bool combinedstats = false)¶
-
Timer
(int num_qubits_, int my_rank_, int num_procs_)¶
-
~Timer
()¶
-
void
Reset
()¶
-
double
Wtime
()¶
-
void
Start
(std::string s, std::size_t cpos, std::size_t tpos = 999999)¶ Start the timer.
-
void
record_sn
(double time, double bw)¶
-
void
record_dn
(double time, double bw)¶
-
void
record_tn
(double time, double bw)¶
-
void
record_cm
(double time, double bw)¶
-
void
Stop
()¶ Stop the timer.
-
void
Breakdown
()¶ Print the statistics to screen.
-
Functions¶
Template Function __attribute__¶
Defined in File highperfkernels.hpp
Function Documentation¶
-
template<typename Type> __attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std __attribute__ ((noinline)) void Loop_TN(Type *state
Function GetQhipsterVersion¶
Defined in File qureg_version.hpp
Function perm¶
Defined in File permute.hpp
Template Function qaoa::GetExpectationValueFromCostFunction¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
QubitRegister<Type>::BaseTypeqaoa
::
GetExpectationValueFromCostFunction
(const QubitRegister<Type> &psi, const QubitRegister<Type> &diag)¶
Template Function qaoa::GetExpectationValueSquaredFromCostFunction¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
QubitRegister<Type>::BaseTypeqaoa
::
GetExpectationValueSquaredFromCostFunction
(const QubitRegister<Type> &psi, const QubitRegister<Type> &diag)¶
Template Function qaoa::GetHistogramFromCostFunction¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
std::vector<typename QubitRegister<Type>::BaseType>qaoa
::
GetHistogramFromCostFunction
(const QubitRegister<Type> &psi, const QubitRegister<Type> &diag, int max_value)¶
Template Function qaoa::GetHistogramFromCostFunctionWithWeightsBinned¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
std::vector<typename QubitRegister<Type>::BaseType>qaoa
::
GetHistogramFromCostFunctionWithWeightsBinned
(const QubitRegister<Type> &psi, const QubitRegister<Type> &diag, double max_value, double bin_width)¶
Template Function qaoa::GetHistogramFromCostFunctionWithWeightsRounded¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
std::vector<typename QubitRegister<Type>::BaseType>qaoa
::
GetHistogramFromCostFunctionWithWeightsRounded
(const QubitRegister<Type> &psi, const QubitRegister<Type> &diag, double max_value)¶
Template Function qaoa::ImplementQaoaLayerBasedOnCostFunction¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
voidqaoa
::
ImplementQaoaLayerBasedOnCostFunction
(QubitRegister<Type> &psi, QubitRegister<Type> &diag, typename QubitRegister<Type>::BaseType gamma)¶
Template Function qaoa::InitializeVectorAsMaxCutCostFunction¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
intqaoa
::
InitializeVectorAsMaxCutCostFunction
(QubitRegister<Type> &diag, std::vector<int> &adjacency)¶
Template Function qaoa::InitializeVectorAsWeightedMaxCutCostFunction¶
Defined in File qaoa_features.hpp
Function Documentation¶
-
template<typename
Type
>
QubitRegister<Type>::BaseTypeqaoa
::
InitializeVectorAsWeightedMaxCutCostFunction
(QubitRegister<Type> &diag, std::vector<typename QubitRegister<Type>::BaseType> &adjacency)¶
Function qhipster::detail::BX¶
Defined in File bitops.hpp
Template Function qhipster::detail::highestBitImpl¶
Defined in File bitops.hpp
Template Function qhipster::floor_power_of_two¶
Defined in File bitops.hpp
Template Function qhipster::ilog2¶
Defined in File bitops.hpp
Function Documentation¶
-
template<class
Integral
>
unsigned intqhipster
::
ilog2
(Integral n)¶ Returns the logarithm base 2 of a non-zero integer.
This function returns the the logarithm base 2 of a non-zero integer
- Pre
The integer
i
is a power of 2- Parameters
[in] i
: the non-zero integer of which the logarithm base 2 is returned
Template Function qhipster::isPowerOf2¶
Defined in File bitops.hpp
Function qhipster::mpi::Barrier¶
Defined in File mpi_env.hpp
Function qhipster::mpi::PoolBarrier¶
Defined in File mpi_env.hpp
Function qhipster::mpi::PoolPrint¶
Defined in File mpi_env.hpp
Function Documentation¶
-
void
qhipster::mpi
::
PoolPrint
(std::string s, bool all = false)¶ Print from all MPI processes.
It prints a string from all processes if
all
is true or just from the master process with rank 0 ifall
is false. If MPI is not present it prints the string.If
all
is set, the string is prefixed by the number of the MPI process.- Parameters
s
: the string to be printedall
: a flag to specify if all processes should print or just the master process
Function qhipster::mpi::Print¶
Defined in File mpi_env.hpp
Function qhipster::mpi::StateBarrier¶
Defined in File mpi_env.hpp
Function qhipster::mpi::StatePrint¶
Defined in File mpi_env.hpp
Function qhipster::popcnt(uint32_t)¶
Defined in File bitops.hpp
Function Documentation¶
Warning
doxygenfunction: Unable to resolve multiple matches for function “qhipster::popcnt” with arguments (uint32_t) in doxygen xml output for project “My Project” from directory: ./doxyoutput/xml. Potential matches:
- long popcnt(uint32_t x)
- long popcnt(uint64_t x)
Function qhipster::popcnt(uint64_t)¶
Defined in File bitops.hpp
Function Documentation¶
Warning
doxygenfunction: Unable to resolve multiple matches for function “qhipster::popcnt” with arguments (uint64_t) in doxygen xml output for project “My Project” from directory: ./doxyoutput/xml. Potential matches:
- long popcnt(uint32_t x)
- long popcnt(uint64_t x)
Template Function qhipster::ShuffleFisherYates¶
Defined in File rng_utils.hpp
Function Documentation¶
-
template<typename
Type
, typenameTypeFloat
>
voidqhipster
::
ShuffleFisherYates
(std::vector<Type> &array, RandomNumberGenerator<TypeFloat> *rnd_generator_ptr, std::string shared = "local")¶
Template Function qhipster::toString¶
Defined in File conversion.hpp
Function Documentation¶
-
template<class
T
>
std::stringqhipster
::
toString
(T const &val)¶ convert to a string
This function converts any value to a string, by writing it into a string stream.
- Pre
Writing into a std::istream using operator<< needs to be implemented for the type
- Parameters
[in] val
: the value to be converted to a string
Function qhipster::WhatCompileDefinitions¶
Defined in File utils.hpp
Function time_in_seconds¶
Defined in File utils.hpp
Variables¶
Variable c11¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t c11
Variable c12¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t c12
Variable c13¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t c13
Variable c21¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t c21
Variable c22¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t std::size_t c22
Variable c23¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t c23
Variable c31¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t c31
Variable c32¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t c32
Variable ind_shift¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t ind_shift
Variable m¶
Defined in File highperfkernels.hpp
Variable Documentation¶
-
__attribute__((noinline)) void Loop_SN(std __attribute__((noinline)) void Loop_DN(std std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t std::size_t TM2x2< Type > const & m
Variable specialize¶
Defined in File highperfkernels.hpp
Variable timer¶
Defined in File highperfkernels.hpp
Defines¶
Define QHIPSTER_MPI_CHECK_RESULT¶
Defined in File mpi_exception.hpp
Define QHIPSTER_VERSION_STRING¶
Defined in File qureg_version.hpp
Typedefs¶
Typedef BaseType¶
Defined in File qureg.hpp
Typedef Documentation¶
-
typedef QubitRegister<Type>::BaseType
NoisyQureg
::
BaseType
¶
Typedef ComplexDP¶
Defined in File utils.hpp
Typedef ComplexSP¶
Defined in File utils.hpp
Typedef TM2x2¶
Defined in File qureg.hpp
Typedef Documentation¶
-
using
TM2x2
= qhipster::TinyMatrix<Type, 2, 2, 32>¶
Typedef TM4x4¶
Defined in File qureg.hpp
Typedef Documentation¶
-
using
TM4x4
= qhipster::TinyMatrix<Type, 4, 4, 32>¶