Skip to content

Commit 9acbf28

Browse files
committed
Merge remote-tracking branch 'iqusoft/intel-qs/development' into ncu
2 parents f3974f9 + eafade6 commit 9acbf28

22 files changed

+639
-67
lines changed

.github/workflows/cpp_build_with_cmake.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
push:
77
branches: [ master ]
88
pull_request:
9-
branches: [ master ]
9+
branches: [ master, development ]
1010

1111
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
1212
jobs:

.github/workflows/python_build_mp.yml

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Python build with MPI
2+
3+
# Triggers the workflow on push or pull request events but only for the master branch
4+
on:
5+
push:
6+
branches: [ master ]
7+
pull_request:
8+
branches: [ master , development ]
9+
10+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
11+
jobs:
12+
# This workflow contains a single job called "build-ubuntu-conda-gcc"
13+
build-ubuntu-conda-gcc:
14+
# The type of runner that the job will run on
15+
runs-on: ubuntu-latest
16+
17+
# Steps represent a sequence of tasks that will be executed as part of the job
18+
steps:
19+
- uses: goanpeca/setup-miniconda@v1
20+
with:
21+
auto-update-conda: true
22+
python-version: 3.7
23+
- name: Conda info, list, pybind install and activate
24+
shell: bash -l {0}
25+
run: |
26+
conda info
27+
conda list
28+
conda install -y pybind11
29+
conda activate /usr/share/miniconda/envs/test
30+
- name: Install MPICH
31+
run: |
32+
sudo apt-get install mpich
33+
which mpic++
34+
mpic++ --version
35+
36+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
37+
- uses: actions/checkout@v2
38+
39+
- name: configure
40+
shell: bash -l {0}
41+
run: mkdir build && cd build && CXX=mpic++ cmake PYTHON_EXECUTABLE=/usr/share/miniconda/envs/test/bin/python -DIqsMPI=ON -DIqsPython=ON -DIqsUtest=OFF ..
42+
- name: build
43+
run: cmake --build build --target intelqs_py
44+
45+
- name: unit test
46+
run: cd unit_test && /usr/share/miniconda/envs/test/bin/python import_iqs.py
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Python build with MPI
2+
3+
# Triggers the workflow on push or pull request events but only for the master branch
4+
on:
5+
push:
6+
branches: [ master ]
7+
pull_request:
8+
branches: [ master , development ]
9+
10+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
11+
jobs:
12+
# This workflow contains a single job called "build-ubuntu-conda-gcc"
13+
build-ubuntu-conda-gcc:
14+
# The type of runner that the job will run on
15+
runs-on: ubuntu-latest
16+
17+
# Steps represent a sequence of tasks that will be executed as part of the job
18+
steps:
19+
- uses: goanpeca/setup-miniconda@v1
20+
with:
21+
auto-update-conda: true
22+
python-version: 3.7
23+
- name: Conda info, list, pybind install and activate
24+
shell: bash -l {0}
25+
run: |
26+
conda info
27+
conda list
28+
conda install -y pybind11
29+
conda activate /usr/share/miniconda/envs/test
30+
- name: Install MPICH
31+
run: |
32+
sudo apt-get install mpich
33+
which mpic++
34+
mpic++ --version
35+
36+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
37+
- uses: actions/checkout@v2
38+
39+
- name: configure
40+
shell: bash -l {0}
41+
run: mkdir build && cd build && CXX=mpic++ cmake PYTHON_EXECUTABLE=/usr/share/miniconda/envs/test/bin/python -DIqsMPI=ON -DIqsPython=ON -DIqsUtest=OFF ..
42+
- name: build
43+
run: cmake --build build --target intelqs_py
44+
45+
- name: unit test
46+
run: cd unit_test && /usr/share/miniconda/envs/test/bin/python import_iqs.py
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Python build (no MPI)
2+
3+
# Triggers the workflow on push or pull request events but only for the master branch
4+
on:
5+
push:
6+
branches: [ master ]
7+
pull_request:
8+
branches: [ master , development ]
9+
10+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
11+
jobs:
12+
# This workflow contains a single job called "build-ubuntu-conda-gcc"
13+
build-ubuntu-conda-gcc:
14+
# The type of runner that the job will run on
15+
runs-on: ubuntu-latest
16+
17+
# Steps represent a sequence of tasks that will be executed as part of the job
18+
steps:
19+
- uses: goanpeca/setup-miniconda@v1
20+
with:
21+
auto-update-conda: true
22+
python-version: 3.7
23+
- name: Conda info, list, pybind install and activate
24+
shell: bash -l {0}
25+
run: |
26+
conda info
27+
conda list
28+
conda install -y pybind11
29+
conda activate /usr/share/miniconda/envs/test
30+
31+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
32+
- uses: actions/checkout@v2
33+
34+
- name: configure
35+
shell: bash -l {0}
36+
run: mkdir build && cd build && CXX=g++ cmake PYTHON_EXECUTABLE=/usr/share/miniconda/envs/test/bin/python -DIqsMPI=OFF -DIqsPython=ON -DIqsUtest=OFF ..
37+
- name: build
38+
run: cmake --build build --target intelqs_py
39+
40+
- name: unit test
41+
run: cd unit_test && /usr/share/miniconda/envs/test/bin/python import_iqs.py

CMakeLists.txt

+9-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
4545
option(IqsMPI "Enable MPI?" OFF)
4646
option(IqsMKL "Enable MKL?" OFF)
4747
option(IqsPython "Enable Python wrap?" OFF)
48-
option(IqsUtest "Enable unit test?" ON)
48+
option(IqsUtest "Enable unit test?" OFF)
4949
option(BuildExamples "Build the Examples" OFF)
5050
option(IqsNative "Enable the latest vector instructions?" OFF)
5151

@@ -57,8 +57,7 @@ if(IqsMPI)
5757
message(STATUS "MPI functionality: enabled.")
5858

5959
if(IqsPython)
60-
message(STATUS "Python not compatible with MPI: disabled.")
61-
set(IqsPython OFF)
60+
message(STATUS "Python interface with MPI: enabled." )
6261
endif()
6362

6463
if(IqsUtest)
@@ -141,6 +140,13 @@ if (IqsNative)
141140
endif()
142141

143142

143+
################################################################################
144+
# Enable compiler optimizations to fix GCC performance.
145+
################################################################################
146+
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
147+
add_compile_options(-O3)
148+
endif()
149+
144150
################################################################################
145151
# Locate MKL if it is already configured through Intel (mklvars.sh) scripts.
146152
# - Follow the Intel compiler documentation to ensure that all of the

README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
![C++ build with CMake](https://github.com/iqusoft/intel-qs/workflows/C++%20build%20with%20CMake/badge.svg)
2-
![Python build (no MPI)](https://github.com/iqusoft/intel-qs/workflows/Python%20build%20(no%20MPI)/badge.svg)
3-
[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=2001.10554&color=success)](https://arxiv.org/abs/2001.10554)
2+
![Python build (no MPI)](https://github.com/iqusoft/intel-qs/workflows/Python%20build%20(no%20MPI)/badge.svg?branch=develop-action)
3+
![Python build with MPI](https://github.com/iqusoft/intel-qs/workflows/Python%20build%20with%20MPI/badge.svg?branch=develop-action)[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=2001.10554&color=success)](https://arxiv.org/abs/2001.10554)
44
[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=1601.07195&color=inactive)](https://arxiv.org/abs/1601.07195)
55

66
# Intel Quantum Simulator
@@ -101,15 +101,16 @@ Underneath, this option uses [`-xhost`](https://software.intel.com/en-us/cpp-com
101101
with Intel compilers and [`-march=native`](https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html) with GNU compilers.
102102

103103

104-
### Enable Python binding (only available without MPI)
104+
### Enable Python binding
105105

106-
By default, whenever MPI is disabled, the building process includes the Python binding for
106+
By default, the compilation does not include the the Python binding for
107107
Intel-QS. The binding code uses the Pybind11 library which needs to be installed via 'conda'
108108
(and not simply with pip) to include the relevant information in CMake.
109109
See [this page](https://github.com/pybind/pybind11/issues/1628) for more info on this issue.
110110

111-
To disable the Python wrap, even without MPI, set the CMake option selection to
112-
`-DIqsPython=OFF`.
111+
To enable the Python wrap set the CMake option selection to
112+
`-DIqsPython=ON`.
113+
This option works also with the MPI buile enabled.
113114

114115

115116
### Unit test

benchmarks/basic_code_for_scaling.cpp

+15-11
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,25 @@ int main(int argc, char **argv)
5858
// Parse input parameters:
5959
for (int i = 1; i < argc; ++i)
6060
{
61-
if (argv[i] == std::string ("-nq")) {
61+
if (argv[i] == std::string ("-nq")) { // number of qubits.
6262
++i;
63-
assert(i<argc); // Unspecified number of qubits.
63+
assert(i<argc);
6464
num_qubits = std::atoi(argv[i]);
65-
} else if (argv[i] == std::string ("-ng")) {
65+
} else if (argv[i] == std::string ("-ng")) { // number of gates.
6666
++i;
67-
assert(i<argc); // Unspecified number of gates.
67+
assert(i<argc);
6868
num_gates = std::atoi(argv[i]);
69-
} else if (argv[i] == std::string ("-nt")) {
69+
} else if (argv[i] == std::string ("-nt")) { // number of threads per rank.
7070
++i;
71-
assert(i<argc); // Unspecified number of threads per rank.
71+
assert(i<argc);
7272
num_threads = std::atoi(argv[i]);
73-
} else if (argv[i] == std::string ("-od")) {
73+
} else if (argv[i] == std::string ("-od")) { // output directory.
7474
++i;
75-
assert(i<argc); // Unspecified output directory.
75+
assert(i<argc);
7676
out_directory = argv[i];
77-
} else if (argv[i] == std::string ("-of")) {
77+
} else if (argv[i] == std::string ("-of")) { // output filename root.
7878
++i;
79-
assert(i<argc); // Unspecified output filename root.
79+
assert(i<argc);
8080
out_filename_root = argv[i];
8181
} else {
8282
std::cout << "Wrong arguments. They should be:\n"
@@ -104,7 +104,11 @@ int main(int argc, char **argv)
104104
G(1, 1) = {0.649564427121402, 0.373855203932477};
105105

106106
// Initialize the qubit register and turn on specialization.
107-
QubitRegister<ComplexDP> psi(num_qubits, "base", 0);
107+
// Since this code may use very large number of qubits, we limit it to 2^30.
108+
size_t tmp_spacesize = 0;
109+
if (num_qubits>30)
110+
tmp_spacesize = size_t(1L << 30);
111+
QubitRegister<ComplexDP> psi(num_qubits, "base", 0, tmp_spacesize);
108112
if (false) psi.TurnOnSpecialize();
109113
// Loop over the number of qubits and store the time elapsed in the computation.
110114
struct timeval time;

benchmarks/script_pcl.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ exec_args=" -nq "$num_qubits" -ng "$num_gates" -od "$out_directory" -of "$out_fi
2323
##########################################################################
2424

2525
exec_name="basic_scaling"
26-
exec_file="../build/bin/basic_code_for_scaling.exe"
26+
exec_file="./bin/basic_code_for_scaling.exe"
2727

2828
##########################################################################
2929

@@ -60,7 +60,7 @@ job_content=\
6060
"export INTEL_LICENSE_FILE=/swtools/intel/licenses/"$'\n'\
6161
"export I_MPI_HYDRA_BOOTSTRAP=slurm"$'\n\n'\
6262
"mpiexec.hydra -genv I_MPI_DEBUG 4 -genv OMP_NUM_THREADS "$num_threads_per_rank\
63-
" -genv KMP_AFFINITY granularity=thread,1,0,verbose -ppn $num_ranks ./"$exec_file" "$exec_args
63+
" -genv KMP_AFFINITY granularity=thread,1,0,verbose -ppn $num_ranks "$exec_file" "$exec_args
6464

6565
echo "$job_content" > $job_file
6666

benchmarks/script_strong_scaling.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fi
4646
exec_args=" -nq "$num_qubits" -ng "$num_gates" -od "$out_directory" -of "$out_filename_root\
4747
" -nt "$num_threads_per_rank
4848

49-
exec_file="../build/bin/basic_code_for_scaling.exe"
49+
exec_file="./bin/basic_code_for_scaling.exe"
5050

5151
##########################################################################
5252

benchmarks/script_weak_scaling.sh

100644100755
+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ out_filename_root="basic_weak_scaling"
3030
min_num_qubits=26
3131
num_gates=1
3232

33-
exec_file="../build/bin/basic_code_for_scaling.exe"
33+
exec_file="./bin/basic_code_for_scaling.exe"
3434

3535
##########################################################################
3636

include/mpi_env.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <string>
1717
#include <unistd.h>
18+
#include <stdexcept>
1819

1920
#ifdef INTELQS_HAS_MPI
2021
#include "mpi_exception.hpp"
@@ -51,6 +52,7 @@ class Environment
5152
/// If MPI is present, but has not been initialized, then MPI_Init will be called.
5253

5354
Environment(int& argc, char**& argv);
55+
Environment();
5456

5557
/// Finalize the MPI Environment
5658
///
@@ -110,7 +112,23 @@ class Environment
110112
static MPI_Comm GetComm();
111113
#endif
112114

115+
116+
/*
117+
The singleton interface that is used for global management
118+
of MPI resources.
119+
*/
120+
static void Init();
121+
static void Init(int &argc, char**&argv);
122+
static void Finalize();
123+
static Environment *GetSharedInstance() {return shared_instance;}
124+
113125
private:
126+
// Shared helper for constructor overload
127+
#ifdef INTELQS_HAS_MPI
128+
void CommonInit(int flag);
129+
#endif
130+
131+
static Environment *shared_instance;
114132

115133
bool inited_;
116134
static bool useful_rank;

include/qureg.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class QubitRegister
106106
std::size_t NumQubits() const { return num_qubits; }
107107
Type *TmpSpace() const { return state + LocalSize(); }
108108
size_t TmpSize() const {return tmp_spacesize_;}
109+
110+
// Useful for python/numpy bindings and other buffer protocols
111+
Type *RawState() { return state; }
112+
109113

110114
// bit manipulation
111115
inline bool check_bit(std::size_t variable, std::size_t position) const

notebooks/python_mpi.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import sys
2+
sys.path.insert(0, '../build/lib')
3+
import intelqs_py as iqs
4+
import numpy as np
5+
6+
7+
def run_circuit(num_qubits):
8+
reg = iqs.QubitRegister(num_qubits, 'base', 0, 0)
9+
for i in range(num_qubits):
10+
reg.ApplyHadamard(i)
11+
reg.ApplyRotationZ(i, np.pi/3)
12+
return reg
13+
14+
15+
if __name__ == '__main__':
16+
if len(sys.argv) <= 1:
17+
print('Usage: {} <num_qubits>'.format(sys.argv[0]))
18+
sys.exit(0)
19+
num_qubits = int(sys.argv[1])
20+
21+
iqs.init()
22+
23+
reg = run_circuit(num_qubits)
24+
state_vector = np.array(reg, copy=False)
25+
26+
rank = iqs.MPIEnvironment.GetRank()
27+
print('\nFinal state at rank {}: {}'.format(rank, state_vector))
28+
29+
iqs.finalize()
30+
31+
# SAMPLE RUNS:
32+
33+
## Single-Process:
34+
'''
35+
python python_mpi.py 4
36+
[|s0>: 0] world_rank: 0 , state_rank: 0 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 1 , threads/rank: 72 --useful
37+
38+
Final state at rank 0: [0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j
39+
0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j
40+
0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j
41+
0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j]
42+
'''
43+
44+
## Multi-Process:
45+
'''
46+
mpiexec -n 2 python python_mpi.py 4
47+
[|s0>: 0] world_rank: 0 , state_rank: 0 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 2 , threads/rank: 36 --useful
48+
[|s0>: 1] world_rank: 1 , state_rank: 1 (state 0 of 1) my_node_id: 0 , num_nodes: 1 , ranks/node: 2 , threads/rank: 36 --useful
49+
50+
Final state at rank 0: [0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j
51+
0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j 0.21650635-0.125j]
52+
53+
Final state at rank 1: [0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j
54+
0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j 0.21650635+0.125j]
55+
'''

0 commit comments

Comments
 (0)