Commit 06067492 authored by Gopalakrishnan Meena, Murali's avatar Gopalakrishnan Meena, Murali
Browse files

Merge branch 'qiskit1.0-port' into 'main'

Qiskit1.0 port

See merge request !1
parents 5babd843 3fed60c5
Loading
Loading
Loading
Loading
+67 −50
Original line number Diff line number Diff line
@@ -40,46 +40,22 @@ All developments were done on [OLCF Andes](https://docs.olcf.ornl.gov/systems/an
      wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
      bash Miniconda3-latest-Linux-x86_64.sh -b -p /global/common/software/m4454/env_muraligm
      source /global/common/software/m4454/env_muraligm/bin/activate
      module load cudatoolkit/11.7
      module load cudatoolkit/12.0
      ```
      </details>

      * Since the QLSA circuit generator ([HHL](https://github.com/anedumla/quantum_linear_solvers)) uses an older qiskit version requiring qiskit-terra, we need to make two envs: (1) to generate the circuit and (2) to run the circuit using qiskit 1.0
      1. Install libraries to generate circuit
            * Make custom conda env
            ```
      conda create --name env_custom python=3.9
      conda activate env_custom
      ```
      * Install qiskit
            conda create --name qlsa-circuit python=3.11
            conda activate qlsa-circuit
            ```
      pip install -r requirements.txt --no-cache-dir
      ```
    * **NOTE:** Make sure to test the installation with the sample codes provided: 
      1. Test qiskit installation: [`test_qiskit_installation.py`](test_qiskit_installation.py)

            * Install qiskit and [linear solver](https://github.com/anedumla/quantum_linear_solvers) package
            ```
            python test_qiskit_installation.py -backtyp ideal
            pip install -r requirements_circuit.txt --no-cache-dir
            ```

            <details><summary>Sample output from the test code:</summary>

            ```
            Backend: QasmSimulator('qasm_simulator')
            Job status is JobStatus.DONE

            Total count for 00 and 11 are: {'00': 494, '11': 506}
                ┌───┐     ┌─┐   
            q_0:┤ H ├──■──┤M├───
                └───┘┌─┴─┐└╥┘┌─┐
            q_1:─────┤ X ├─╫─┤M├
                     └───┘ ║ └╥┘
            c:2/═══════════╩══╩═
                           0  1 
            ```
            </details>

            * Change `-backtyp` for different backends.
            * **NOTE:** To run using IBM Provider, you need to add your IBM Quantum Computing API KEY and instance to the `keys.sh` file and source activate it.
      2. Test [linear solver package](https://github.com/anedumla/quantum_linear_solvers): [`test_linear_solver.py`](test_linear_solver.py)
            * Test [linear solver package](https://github.com/anedumla/quantum_linear_solvers): [`test_linear_solver.py`](test_linear_solver.py)

            ```
            python test_linear_solver.py -nq 2
@@ -144,10 +120,47 @@ All developments were done on [OLCF Andes](https://docs.olcf.ornl.gov/systems/an
            ```
            </details>
      
      2. Install libraries to run the circuit
            * Make custom conda env
            ```
            conda create --name qlsa-solver python=3.11
            conda activate qlsa-solver
            ```
            * Install qiskit and other packages
            ```
            pip install -r requirements_solver.txt --no-cache-dir
            ```

            * Test qiskit installation: [`test_qiskit_installation.py`](test_qiskit_installation.py)

            ```
            python test_qiskit_installation.py -backtyp ideal
            ```

            <details><summary>Sample output from the test code:</summary>

            ```
            Backend: QasmSimulator('qasm_simulator')
            Job status is JobStatus.DONE

            Total count for 00 and 11 are: {'00': 494, '11': 506}
                ┌───┐     ┌─┐   
            q_0:┤ H ├──■──┤M├───
                └───┘┌─┴─┐└╥┘┌─┐
            q_1:─────┤ X ├─╫─┤M├
                     └───┘ ║ └╥┘
            c:2/═══════════╩══╩═
                           0  1 
            ```
            </details>

            * Change `-backtyp` for different backends.
            * **NOTE:** To run using IBM Provider, you need to add your IBM Quantum Computing API KEY and instance to the `keys.sh` file and source activate it.

2. Install GPU version of Aer simulator (skip for Frontier):

    ```
    pip install qiskit-aer-gpu==0.13.3 --no-cache-dir
    pip install qiskit-aer-gpu==0.14.2 --no-cache-dir
    ```
    <details><summary>Notes for Perlmutter:</summary>
    
@@ -157,11 +170,15 @@ All developments were done on [OLCF Andes](https://docs.olcf.ornl.gov/systems/an
      ```
      Or
      ```
      export LD_LIBRARY_PATH=/global/common/software/m4454/env_muraligm/envs/env_custom/lib/python3.9/site-packages/nvidia/cuda_runtime/lib:/global/common/software/m4454/env_muraligm/envs/env_custom/lib/python3.9/site-packages/cuquantum/lib:/global/common/software/m4454/env_muraligm/envs/env_custom/lib/python3.9/site-packages/cutensor/lib:$LD_LIBRARY_PATH
      export LD_LIBRARY_PATH=/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/nvidia/cuda_runtime/lib:/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/cuquantum/lib:/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/cutensor/lib:/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/nvidia/nvjitlink/lib:$LD_LIBRARY_PATH
      ```
      </details>

    * **NOTE:** Make sure to test the installation with the sample code provided: [`test_gpu.py`](test_gpu.py)
    * **NOTE:** Make sure to test the installation:
      ```
      python -c "from qiskit_aer import AerSimulator; simulator = AerSimulator(); print(simulator.available_devices())"
      ```
      * with the sample code provided: [`test_gpu.py`](test_gpu.py)

      ```
      python test_gpu.py -nq 2 --gpu
@@ -234,7 +251,7 @@ All developments were done on [OLCF Andes](https://docs.olcf.ornl.gov/systems/an

      ```
      source /global/common/software/m4454/env_muraligm/bin/activate
      module load cudatoolkit/11.7
      module load cudatoolkit/12.0
      conda activate env_custom
      source init_perlmutter.sh
      ```
@@ -246,9 +263,9 @@ All developments were done on [OLCF Andes](https://docs.olcf.ornl.gov/systems/an
      ```
      * Change `nq` to change size of system of equations
  
3. Run generalized QLSA script for various use-cases: [`linear_solver.py`](linear_solver.py)
3. Run QLSA circuit generator script for various use-cases: [`circuit_HHL.py`](circuit_HHL.py)
    ```
    srun -N1 -n1 -c2 python linear_solver.py -case [case-name] -casefile [case-var-file] -s [#-shots]  --savedata[optional but recommended]
    srun -N1 -n1 -c2 python circuit_HHL.py -case [case-name] -casefile [case-var-file] --savedata
    ```
      <details><summary>Sample output for Hele-Shaw flow, solving for pressure:</summary>

circuit_HHL.py

0 → 100644
+91 −0
Original line number Diff line number Diff line
# Introduction
'''
Script to generate HHL circuit that solves any Ax=b problem.
Function `func_matrix_vector.py` is used to define A and b.
Sample code run script:
python circuit_HHL.py -case sample-tridiag -casefile input_vars.yaml --savedata
'''

import numpy as np

# Importing standard Qiskit libraries
from qiskit import QuantumCircuit, transpile
from qiskit import qpy
from qiskit_aer import AerSimulator
from linear_solvers import NumPyLinearSolver, HHL
# library to generate matrix and vector for linear system of equations
import func_matrix_vector as matvec

import time
import os
import argparse
import pickle

parser = argparse.ArgumentParser()
parser.add_argument("-case", "--case_name",  type=str, default='ideal', required=False, help="Name of the problem case: 'sample-tridiag', 'hele-shaw'")
parser.add_argument("-casefile", "--case_variable_file",  type=str, default='ideal', required=False, help="YAML file containing variables for the case: 'input_vars.yaml'")
parser.add_argument("--gpu", default=False, action='store_true', help="Use GPU backend for Aer simulator.")
parser.add_argument("--gpumultiple", default=False, action='store_true', help="Use multiple GPUs for the backend of Aer simulator.")
parser.add_argument("--drawcirc", default=False, action='store_true', help="Draw circuit.")

parser.add_argument("--savedata", default=False, action='store_true', help="Save data at `models/<filename>` with `<filename>` based on parameters.")
args = parser.parse_args()

if __name__ == '__main__':
    # Get system matrix and vector
    matrix, vector, input_vars = matvec.get_matrix_vector(args)
    MATRIX_SIZE = matrix.shape[0]
    n_qubits_matrix = int(np.log2(MATRIX_SIZE))
    
    # setup quantum backend
    backend_type = 'ideal'
    backend_method = 'statevector'
    print(f'Using \'{backend_type}\' simulator with \'{backend_method}\' backend')
    if args.gpu: backend = AerSimulator(method=backend_method, device='GPU')
    elif args.gpumultiple: backend = AerSimulator(method=backend_method, device='GPU', blocking_enable=True, blocking_qubits=18)
    else: backend = AerSimulator(method=backend_method)
    print(f'Backend: {backend}')
    
    # setup HHL solver
    # backend_init = qc_backend('ideal', 'statevector', args)
    hhl = HHL(quantum_instance=backend)
    
    # Solutions
    # classical soultion
    t = time.time()
    classical_solution = NumPyLinearSolver().solve(matrix, vector/np.linalg.norm(vector))
    t_classical = time.time() - t
    print(f'Time elapsed for classical:  {int(t_classical/60)} min {t_classical%60:.2f} sec', flush=True)
    
    # generate HHL circuit
    print(f'==================Generating HHL circuit================', flush=True)
    t = time.time()
    circ = hhl.construct_circuit(matrix, vector)
    t_circ = time.time() - t
    print(f'Time elapsed for generating HHL circuit:  {int(t_circ/60)} min {t_circ%60:.2f} sec')
    
    # Save data
    if args.savedata:
        circ_transpile = transpile(circ, backend)
        # save metadata (DON'T USE Pickle to save the circuit - only works for a given version)
        save_data = {   'args'                  : args,
                        'input_vars'            : input_vars,
                        'matrix'                : matrix,
                        'vector'                : vector,
                        't_circ'                : t_circ}
        filename = input_vars['savefilename'].format(**input_vars)
        savefilename = f'{filename}_circ_nqmatrix{n_qubits_matrix}'
        file = open(f'{savefilename}.pkl', 'wb')
        pickle.dump(save_data, file)
        file.close()
        # save circuit as QPY file
        with open(f'{savefilename}.qpy', 'wb') as fd:
            qpy.dump(circ_transpile, fd)
        print("===========Circuit saved===========")
    
    # Plot circuit
    if args.drawcirc:
        circ.measure_all()
        print(f'Circuit:\n{circ.draw()}', flush=True)

+7 −7
Original line number Diff line number Diff line
@@ -30,9 +30,9 @@ def sample_tridiag(doc_id, args):
    input_vars = get_yaml(args.case_variable_file, doc_id)
    print(f"Case: {input_vars['case_name']}")
    filename = input_vars['savefilename'].format(**input_vars)
    NUM_QUBITS = input_vars['NUM_QUBITS']
    n_qubits_matrix = input_vars['NQ_MATRIX']
    # custom systems
    MATRIX_SIZE = 2 ** NUM_QUBITS
    MATRIX_SIZE = 2 ** n_qubits_matrix
    
    # entries of the tridiagonal Toeplitz symmetric matrix
    a = 1
@@ -41,7 +41,7 @@ def sample_tridiag(doc_id, args):
                 [-1, 0, 1],
                 shape=(MATRIX_SIZE, MATRIX_SIZE)).toarray()
    vector = np.array([1] + [0]*(MATRIX_SIZE - 1))
    return matrix, vector, filename
    return matrix, vector, input_vars

def Hele_Shaw(doc_id, args):
    input_vars = get_yaml(args.case_variable_file, doc_id)
@@ -138,7 +138,7 @@ def Hele_Shaw(doc_id, args):
    
    if args.savedata == True:
        MATRIX_SIZE = A_herm.shape[0]
        NUM_QUBITS = int(np.log2(MATRIX_SIZE))
        n_qubits_matrix = int(np.log2(MATRIX_SIZE))
        save_data = {'P_in'                  : P_in,
                     'P_out'                 : P_out,
                     'U_top'                 : U_top,
@@ -151,14 +151,14 @@ def Hele_Shaw(doc_id, args):
                     'ny'                    : ny,
                     'A_herm'                : A_herm,
                     'B_herm'                : B_herm,
                     'NUM_QUBITS'            : NUM_QUBITS,
                     'n_qubits_matrix'       : n_qubits_matrix,
                     'args'                  : args}
        file = open(f'{filename}_metadata.pkl', 'wb')
        pickle.dump(save_data, file)
        file.close()
        print("===========Metadata saved===========")
    
    return A_herm, B_herm, filename
    return A_herm, B_herm, input_vars

def Cylinder_2D(doc_id, args):
    input_vars = get_yaml(args.case_variable_file, doc_id)
@@ -195,7 +195,7 @@ def Cylinder_2D(doc_id, args):
    
    print(f'Reformatted A_herm:\n{A_herm}\nB_herm:\n{B_herm}')
    print(f'Determinant of resulting matrix: {np.linalg.det(A_herm)}\nCondition # of resulting matrix: {np.linalg.cond(A_herm)}')
    return A_herm, B_herm, filename
    return A_herm, B_herm, input_vars

# Functions
def next_power_of_2(x):
+115 −110

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Diff line number Diff line
#!/bin/bash

export LD_LIBRARY_PATH=/global/common/software/m4454/env_muraligm/envs/env_custom/lib/python3.9/site-packages/nvidia/cuda_runtime/lib:/global/common/software/m4454/env_muraligm/envs/env_custom/lib/python3.9/site-packages/cuquantum/lib:/global/common/software/m4454/env_muraligm/envs/env_custom/lib/python3.9/site-packages/cutensor/lib:$LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/nvidia/cuda_runtime/lib:/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/cuquantum/lib:/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/cutensor/lib:/global/common/software/m4454/env_muraligm/envs/qlsa-solver/lib/python3.11/site-packages/nvidia/nvjitlink/lib:$LD_LIBRARY_PATH
Loading