Hyppää sisältöön

Welcome to our weekly research support coffee hour on Zoom! Click here for more information.

Warning!

Puhti scratch disk is becoming very full (80+ % ) resulting in performance degradation. Everybody is advised to only keep actively processed data on scratch, all other data should be deleted, transferred to host institute or stored in Lumi-O. No new quota will be granted. Click here for a tool for examining your disk usage.

Qiskit

Qiskit on avoimen lähdekoodin ohjelmisto kvanttitietokoneiden kanssa työskentelyyn piirien, pulssien ja algoritmien tasolla. Tämä sivu sisältää tietoa kvanttisimulaatioiden ajamisesta qiskitillä singularity-kontin sisällä. Jos etsit tietoa töiden ajamisesta fyysisillä kvanttitietokoneilla qiskitillä, katso tämä dokumentaatio: Kvanttitöiden ajaminen.

Uutiset

19.02.2025 Asennettiin qiskit/1.3.2 singularity-konttiin LUMIin kaikkien tärkeimpien Qiskit-pakettien kanssa ja lisättiin tuki monisolmuiselle natiiville Cray MPI GPU -kiihdytykselle, mikä mahdollistaa suorituskykyiset monisolmuiset simulaatiot jopa 44* kubittiin asti. Qiskit-aer on myös päivitetty versioon 0.16

Saatavilla

Tällä hetkellä tuetut Qiskit-versiot:

Versio Moduuli Puhti Mahti LUMI Huomautukset
1.1.1 qiskit/1.1.1 X X
1.3.2 X Natiivi Cray MPI GPU-tuella

Sisältää kaikki tärkeimmät Qiskit-paketit (Terra, Nature, Aer jne.) sekä GPU-kiihdytyksen. Paketit qiskit/1.1.1 ja qiskit/1.3.2 sisältävät հետևavat qiskit-liitännäiset:

qiskit=1.1.1
qiskit-aer-gpu>=0.14.2
qiskit-algorithms==0.3.0
qiskit-dynamics==0.5.1
qiskit-experiments==0.7.0
qiskit-finance==0.4.1
qiskit-ibm-experiment==0.4.7
qiskit-machine-learning==0.7.2
qiskit-nature==0.7.2
qiskit-optimization==0.6.1
qiskit=1.1.1
qiskit-aer-gpu>=0.14.2
qiskit-algorithms==0.3.0
qiskit-dynamics==0.5.1
qiskit-experiments==0.7.0
qiskit-finance==0.4.1
qiskit-ibm-experiment==0.4.7
qiskit-machine-learning==0.7.2
qiskit-nature==0.7.2
qiskit-optimization==0.6.1
qiskit==1.3.2
qiskit-aer-gpu==0.16.0
qiskit-algorithms==0.3.1
qiskit-dynamics==0.5.1
qiskit-experiments==0.8.1
qiskit-finance==0.4.1
qiskit-ibm-experiment==0.4.8
qiskit-machine-learning==0.8.2
qiskit-nature==0.7.2
qiskit-optimization==0.6.1
qiskit_qasm3_import==0.5.1

Jos huomaat, että jokin paketti puuttuu, voit usein asentaa sen itse komennolla pip install --user. Katso Pythonin käyttöoppaastamme lisätietoja siitä, miten voit asentaa paketteja itse. Jos mielestäsi jokin tärkeä Qiskitiin liittyvä paketti pitäisi sisällyttää CSC:n tarjoamaan moduuliin, ole hyvä ja ota yhteyttä asiakastukeemme.

Kaikki moduulit perustuvat kontteihin, joissa käytetään Apptaineria (aiemmin tunnettu nimellä Singularity). Tarjolla on wrapper-skriptejä, jotta yleiset komennot kuten python, python3, pip ja pip3 toimivat normaalisti. Lisätietoja löytyy kohdasta CSC:n yleiset ohjeet Apptainer-konttien ajamiseen.

Lisenssi

Qiskit on lisensoitu Apache License 2.0 -lisenssillä.

Käyttö

Oletusversion käyttämiseksi alusta se komennolla:

module load qiskit

Jos haluat käyttää tiettyä versiota (katso yllä saatavilla olevat versiot), käytä:

module load qiskit/1.1.1

Esimerkki sbatch- ja python-skriptistä - yhden solmun simulaatiot Puhdissa, Mahdissa ja LUMIssa

Esimerkki <sbatch_script_name>.sh-skriptistä yhden GPU:n ja kahden CPU-ytimen varaamiseen yhdellä solmulla Puhdissa ja Mahdissa sekä kaikkien CPU/GPU-resurssien varaamiseen yhdellä solmulla LUMIn standard-g-partitiolla:

#!/bin/bash
#SBATCH --job-name=aer_job
#SBATCH --output=aer_job.o%j
#SBATCH --error=aer_job.e%j
#SBATCH --account=<project>
#SBATCH --partition=gpu
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=2
#SBATCH --mem=8G
#SBATCH --time=1:00:00
#SBATCH --gres=gpu:v100:1

module load qiskit
srun python myprog.py <options>
#!/bin/bash
#SBATCH --job-name=aer_job
#SBATCH --output=aer_job.o%j
#SBATCH --error=aer_job.e%j
#SBATCH --account=<project>
#SBATCH --partition=gpusmall
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=2
#SBATCH --time=1:00:00
#SBATCH --gres=gpu:a100:1

module load qiskit
srun python myprog.py <options>
#!/bin/bash
#SBATCH --job-name=aer_job
#SBATCH --output=aer_job.o%j
#SBATCH --error=aer_job.e%j
#SBATCH --account=<project_id>
#SBATCH --time=2:00:00
#SBATCH --partition=standard-g
#SBATCH --nodes=1
#SBATCH --gpus-per-node=8
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=56

export LUMI_QISKIT_SINGULARITY_CONTAINER_PATH=/appl/local/quantum/qiskit/qiskit_1.3.2_csc.sif
export WRAPPER_PATH=/appl/local/quantum/qiskit/run-singularity

echo "NODES                   : ${SLURM_NNODES}"
echo "TASKS PER NODE          : ${SLURM_NTASKS_PER_NODE}"
echo "CPUS PER TASK           : ${SLURM_CPUS_PER_TASK}"
echo "GPUS PER NODE           : ${SLURM_GPUS_PER_NODE}"
echo "GPUS PER TASK           : ${SLURM_GPUS_PER_TASK}"

mask=mask_cpu:0xfe000000000000,0xfe00000000000000,0xfe0000,0xfe000000,0xfe,0xfe00,0xfe00000000,0xfe0000000000
export MPICH_GPU_SUPPORT_ENABLED=1

srun --cpu-bind=$mask $WRAPPER_PATH $LUMI_QISKIT_SINGULARITY_CONTAINER_PATH python myprog.py

Esimerkki <myprog>.py-python-skriptistä yhden solmun simulaatioihin. Huomaa, että tämä koodi on tarkoitettu vain syntaksin havainnollistamiseen ja toimii vain yhdellä solmulla. LUMI-simulaatioissa katso alla olevasta taulukosta resurssivaatimukset suhteessa simuloitavien kubittien määrään.

from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator

## CHOOSE PARAMETERS
num_qubits = 5              # Number of qubits in the circuit
num_shots = 1000            # How many times we sample the circuit

## CREATE CIRCUIT FOR N-QUBIT GHZ-STATE
circuit = QuantumCircuit(num_qubits)
circuit.h(0)
for i in range(1,num_qubits):
    circuit.cx(0,i)
circuit.measure_all()

## INITIALIZE SIMULATOR BACKEND THAT RUNS ON GPU
simulator = AerSimulator(method="statevector", device="GPU")

## RUN THE CIRCUIT WITH CUSTATEVEC ENABLED
result_statevec = simulator.run(circuit, shots=num_shots, seed_simulator=12345, cuStateVec_enable=True).result()

## PRINT RESULTS
counts = result_statevec.get_counts()
print(f"Counts:, {counts}")
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator

## CHOOSE PARAMETERS
num_qubits = 5              # Number of qubits in the circuit
num_shots = 1000            # How many times we sample the circuit

## CREATE CIRCUIT FOR N-QUBIT GHZ-STATE
circuit = QuantumCircuit(num_qubits)
circuit.h(0)
for i in range(1,num_qubits):
    circuit.cx(0,i)
circuit.measure_all()

## INITIALIZE SIMULATOR BACKEND THAT RUNS ON GPU
simulator = AerSimulator(method="statevector", device="GPU")

## RUN THE CIRCUIT WITH CUSTATEVEC ENABLED
result_statevec = simulator.run(circuit, shots=num_shots, seed_simulator=12345, cuStateVec_enable=True).result()

## PRINT RESULTS
counts = result_statevec.get_counts()
print(f"Counts:, {counts}")
from qiskit import QuantumCircuit, transpile
from qiskit.transpiler import CouplingMap
from qiskit_aer import AerSimulator
from qiskit.circuit.library import QuantumVolume

## CHOOSE PARAMETERS
num_qubits = 34                       # Number of qubits in the circuit
circuit_depth = 30                    # Layers in quantum volume circuit
num_shots = 1000                      # How many times we sample the circuit
sim_method = 'statevector'            # Choosing simulation method
sim_device = 'GPU'                    # Choose whether simulation is run on CPUs or GPUs
use_cache_blocking = True             # Cache blocking technique parallelizes simulation by distributing quantum states into distributed memory space
num_blocking_qubits = 29              # Defines chunk size for cache blocking. Must be smaller than "qubits-log2(number-of-processes)"
use_batched_shots = True              # Distributing shots to multiple processess
num_parallel_experiments = 1          # Does not seem to do anything when running with MPI, probably intended to be used with multithreading

## INITIALIZE SIMULATOR BACKEND
simulator = AerSimulator(method=sim_method, device=sim_device, batched_shots_gpu=use_batched_shots)

## CREATE QUANTUM VOLUME CIRCUIT
circuit = QuantumVolume(num_qubits, circuit_depth, seed=0)
circuit.measure_all()

## TRANSPILE THE CIRCUIT FOR SPECIFIC COUPLING MAP
coupling_map = CouplingMap.from_full(num_qubits)
transpiled_circuit = transpile(circuit, simulator, coupling_map=coupling_map, optimization_level=0)

## RUN THE SIMULATION
result_statevec = simulator.run(transpiled_circuit, shots=num_shots, seed_simulator=12345, blocking_enable=use_cache_blocking, blocking_qubits=num_blocking_qubits, max_parallel_experiments=num_parallel_experiments).result()

## GATHER THE RESULTS AND SOME ADDITIONAL METADATA
counts = result_statevec.get_counts()
result_dict = result_statevec.to_dict()
metadata = result_dict['metadata']
input_data = {'Circuit' : 'Quantum Volume', 'Qubits' : num_qubits, 'Depth' : circuit_depth, 'Shots' : num_shots, 'Batched Shots' : use_batched_shots , 'Device' : sim_device, 'Simulation Method' : sim_method}
if (use_cache_blocking):
    num_chunks = 2**(num_qubits - num_blocking_qubits)
    input_data['Blocking Qubits'] = num_blocking_qubits
    input_data['Number of Chunks'] = num_chunks


## PRINT FOR ONE MPI RANK
if (metadata['mpi_rank'] == 0):
    print()
    print(f"Input data: {input_data}")
    print(f"Metadata: {metadata}")
    #print(f"Results: {counts}")
    print(f"-------------------- \n")

## PRINT ALL MPI PROCESSES
#print(f"Input data: {input_data}")
#print(f"Metadata: {metadata}")
#print(f"-------------------- \n")

Lähetä skripti komennolla sbatch <sbatch_script_name>.sh

Esimerkki sbatch- ja python-skriptistä - monisolmuiset simulaatiot, jotka hyödyntävät natiivia HPE Cray MPI:tä GPU-kiihdytyksellä LUMIssa

Esimerkki <sbatch_MPI_script_name>.sh-skriptistä simulaation ajamiseen usealla LUMI-solmulla standard-g-partitiossa käyttäen kaikkia GPU:ita ja kaikkia CPU-ytimiä solmulla. Tämä on tarkoitettu simulaatioille, joissa on 35 kubittia tai enemmän (enintään 45* kubittia - katso alla olevasta taulukosta suositellut resurssivaraukset simuloitavien kubittien määrän perusteella):

#!/bin/bash
## Here is an example sbatch script for a 38 qubit quantum volume simulation (myprog_MPI.py) using 16 nodes 
#SBATCH --job-name=aer_job
#SBATCH --output=aer_job.o%j
#SBATCH --error=aer_job.e%j
#SBATCH --account=<project_id>
#SBATCH --time=2:00:00
#SBATCH --partition=standard-g
#SBATCH --nodes=16
#SBATCH --gpus-per-node=8
#SBATCH --ntasks-per-node=8
#SBATCH --cpus-per-task=7

export LUMI_QISKIT_SINGULARITY_CONTAINER_PATH=/appl/local/quantum/qiskit/qiskit_1.3.2_csc.sif
export GPU_WRAPPER_PATH=/appl/local/quantum/qiskit/run-singularity-with-gpu-affinity

mask=mask_cpu:0xfe000000000000,0xfe00000000000000,0xfe0000,0xfe000000,0xfe,0xfe00,0xfe00000000,0xfe0000000000
export MPICH_GPU_SUPPORT_ENABLED=1 

srun --cpu-bind=$mask $GPU_WRAPPER_PATH $LUMI_QISKIT_SINGULARITY_CONTAINER_PATH python myprog_MPI.py

Pieni koodiesimerkki <myprog_MPI>.py-python-skriptistä, jossa käytetään 38 kubittia ja jonka suosittelemme ajamaan 16 solmulla
*katso viitteeksi alla oleva suositeltu resurssivaraustaulukko

from qiskit import QuantumCircuit, transpile
from qiskit.transpiler import CouplingMap
from qiskit_aer import AerSimulator
from qiskit.circuit.library import QuantumVolume

## CHOOSE PARAMETERS
num_qubits = 38                       # Number of qubits in the circuit
circuit_depth = 30                    # Layers in quantum volume circuit
num_shots = 1000                      # How many times we sample the circuit
sim_method = 'statevector'            # Choosing simulation method
sim_device = 'GPU'                    # Choose whether simulation is run on CPUs or GPUs
use_cache_blocking = True             # Cache blocking technique parallelizes simulation by distributing quantum states into distributed memory space
num_blocking_qubits = 29              # Defines chunk size for cache blocking. Must be smaller than "qubits-log2(number-of-processes)"
use_batched_shots = True              # Distributing shots to multiple processess
num_parallel_experiments = 1          # Does not seem to do anything when running with MPI, probably intended to be used with multithreading

## INITIALIZE SIMULATOR BACKEND
simulator = AerSimulator(method=sim_method, device=sim_device, batched_shots_gpu=use_batched_shots)

## CREATE QUANTUM VOLUME CIRCUIT
circuit = QuantumVolume(num_qubits, circuit_depth, seed=0)
circuit.measure_all()

## TRANSPILE THE CIRCUIT FOR SPECIFIC COUPLING MAP
coupling_map = CouplingMap.from_full(num_qubits)
transpiled_circuit = transpile(circuit, simulator, coupling_map=coupling_map, optimization_level=0)

## RUN THE SIMULATION
result_statevec = simulator.run(transpiled_circuit, shots=num_shots, seed_simulator=12345, blocking_enable=use_cache_blocking, blocking_qubits=num_blocking_qubits, max_parallel_experiments=num_parallel_experiments).result()

## GATHER THE RESULTS AND SOME ADDITIONAL METADATA
counts = result_statevec.get_counts()
result_dict = result_statevec.to_dict()
metadata = result_dict['metadata']
input_data = {'Circuit' : 'Quantum Volume', 'Qubits' : num_qubits, 'Depth' : circuit_depth, 'Shots' : num_shots, 'Batched Shots' : use_batched_shots , 'Device' : sim_device, 'Simulation Method' : sim_method}
if (use_cache_blocking):
    num_chunks = 2**(num_qubits - num_blocking_qubits)
    input_data['Blocking Qubits'] = num_blocking_qubits
    input_data['Number of Chunks'] = num_chunks


## PRINT FOR ONE MPI RANK
if (metadata['mpi_rank'] == 0):
    print()
    print(f"Input data: {input_data}")
    print(f"Metadata: {metadata}")
    #print(f"Results: {counts}")
    print(f"-------------------- \n")

## PRINT ALL MPI PROCESSES
#print(f"Input data: {input_data}")
#print(f"Metadata: {metadata}")
#print(f"-------------------- \n")

Lähetä skripti komennolla sbatch <sbatch_MPI_script_name>.sh

Ohjeet LUMIn resurssien varaamiseen

Statevector-simulaation vaatima muisti kaksinkertaistuu jokaisen lisätyn kubitin myötä. Käytettäessä 16 tavun tarkkuutta (qiskit-aerin oletus), LUMI tukee statevector-simulaatioita enintään 34 kubittiin yhdellä solmulla ja enintään 44* kubittiin 1024 solmulla cache blocking -tekniikkaa käyttäen. Cache blocking hyödyntää GPU-muistin hajautettuja muistialueita simulaation rinnakkaistamiseen. Hajautettujen prosessien koko määritellään blocking qubits -parametreilla, jotka eivät voi olla suurempia kuin yhden välimuistin koko. LUMIssa välimuistin tulisi vastata yhden GPU:n muistia, eikä blocking qubits -arvo saa olla suurempi kuin 29.

Alla oleva taulukko esittää esimerkkiparametreja Quantum Volume -piirin, jonka syvyys on 30, simulointiin eri kubittimäärillä LUMIn standard-g-partitiossa. Statevectorin vaatima muisti on laskettu 16 tavun tarkkuudella. Käytettyjen solmujen määrä vastaa kaksinkertaista statevectorin vaatimaa muistimäärää, mikä tuottaa optimaalisen suorituskyvyn varaamalla lisämuistia cache blockingia varten hajautettujen prosessien välisen tiedonvaihdon käsittelyyn. Huomaa, että nämä parametrit testattiin tietylle piirille. Solmujen määrän muuttaminen tai erilaisten piirien simulointi voi vaatia erilaisten blocking qubits -määrien määrittämistä.

Muistivaatimukset ja esimerkkiparametrit quantum volume -statevector-simulaatiolle, kun piirin syvyys on 30 ja tarkkuus 16 tavua

# kubitteja # blocking qubits Suositeltu # solmuja # gpus-per-node # tasks-per-node # gpus-per-task # cpus-per-task Kubittimuistin vaatimukset
1 0 1 8 1 8 56 32 tavua
2 0 1 8 1 8 56 64
3 0 1 8 1 8 56 128
4 0 1 8 1 8 56 256
5 0 1 8 1 8 56 512
6 0 1 8 1 8 56 1024
7 0 1 8 1 8 56 2 kilotavua
8 0 1 8 1 8 56 4
9 0 1 8 1 8 56 8
10 0 1 8 1 8 56 16
11 0 1 8 1 8 56 32
12 0 1 8 1 8 56 64
13 0 1 8 1 8 56 128
14 0 1 8 1 8 56 256
15 0 1 8 1 8 56 512
16 0 1 8 1 8 56 1024
17 0 1 8 1 8 56 2 megatavua
18 0 1 8 1 8 56 4
19 0 1 8 1 8 56 8
20 0 1 8 1 8 56 16
21 0 1 8 1 8 56 32
22 0 1 8 1 8 56 64
23 0 1 8 1 8 56 128
24 0 1 8 1 8 56 256
25 0 1 8 1 8 56 512
26 0 1 8 1 8 56 1024
27 0 1 8 1 8 56 2 gigatavua
28 0 1 8 1 8 56 4
29 0 1 8 1 8 56 8
30 29 1 8 1 8 56 16
31 29 1 8 1 8 56 32
32 29 1 8 1 8 56 64
33 29 1 8 1 8 56 128
34 29 1 8 1 8 56 256
35 29 2 8 8 1 7 512
36 29 4 8 8 1 7 1024
37 29 8 8 8 1 7 2 teratavua
38 29 16 8 8 1 7 4
39 29 32 8 8 1 7 8
40 29 64 8 8 1 7 16
41 29 128 8 8 1 7 32
42 29 256 8 8 1 7 64
43 29 512 8 8 1 7 128
44 29 1024 8 8 1 7 256
  • Jos LUMIin lähetetty työ vaatii yli 1024 solmua, resurssien varaamista varten on tehtävä erityinen hero run -hakemus.

Enemmän kuin tehokas vähimmäismäärä LUMI-resursseja simulaatiolle

Simulaation suoritusaikaa on mahdollista nopeuttaa lisäämällä resurssien määrää tehokkaan vähimmäissolmujen määrän yli, joka vastaa kaksinkertaista statevectorin muistivaatimusta. Tällaisissa tapauksissa hajautettujen prosessien (MPI_Ranks) määrä ja varatut resurssit on harkittava huolellisesti. Blocking qubits tulee määrittää siten, ettei MPI-rankkeja ole enempää kuin välimuisteja. Alla olevat kaavat antavat suuntaa työn enimmäissolmujen määrän arviointiin.

            Statevector memory required for n-qubits = precision*2^n
  Cache memory required for nc-cache-blocking-qubits = precision*2^nc

                                       Max MPI-ranks = (Statevector Memory)/(Cache Memory)
                                       Max MPI-ranks = (precision*2^n)/(precision*2^nc) = 2^(n-nc)

                                           Max Nodes = (Max MPI-Ranks)/(Tasks Per Node)

Lisätietoja

Suomenkielinen tekoälykäännös

Sisällössä voi esiintyä virheellistä tietoa tekoälykäännöksestä johtuen.

Klikkaa tästä antaaksesi palautetta